Files
mtgodot-poc/audit/history.jsonl
T
shenleiandClaude Sonnet 5 c5c183da37 fix(movement): remove unreferenced [0.25,3.0] clamp on local player's movSpd scale
CInstanceBase::SetMoveSpeed only guards moving_speed > 1100 -> 0; the local
player's set_server_speed() was additionally floor/ceil-clamping the scale to
an arbitrary [0.25, 3.0] band with no basis in the reference or in this
project's already-fixed remote-entity equivalent (EntityStore::motion_move_speed).
A heavy haste stack or slow debuff on the local player would silently diverge
from what everyone else sees. Removed the extra clamp; kept the moving_speed<=0
early-return guard against pre-spawn/malformed values.

audit: movement.keyboard.motion/server-speed-scale-clamp closed with reference
citation, regression test, and full related-suite pass; contract stays PARTIAL.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 16:31:17 +09:00

486 lines
514 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"time":"2026-09-19T00:00:00Z","event":"ledger_initialized","schema_version":1}
{"time":"2026-09-20T00:00:00Z","event":"status_changed","id":"network.login.phase_flow","from":"UNMAPPED","to":"MAPPED","reason":"initial 40250/client call-chain mapping created; branch equivalence not yet verified"}
{"time":"2026-09-20T00:00:00Z","event":"status_changed","id":"movement.keyboard.motion","from":"UNMAPPED","to":"MAPPED","reason":"initial 40250/client call-chain mapping created; existing tests retained as evidence candidates only"}
{"time":"2026-09-20T00:00:00Z","event":"status_changed","id":"combat.death.exp_drop","from":"UNMAPPED","to":"PARTIAL","reason":"existing reported attack/experience discrepancies require complete packet and motion audit"}
{"time":"2026-09-20T00:00:00Z","event":"status_changed","id":"skill.cast.effect_timing","from":"UNMAPPED","to":"PARTIAL","reason":"local tests cover components but complete 40250 skill timing equivalence is not established"}
{"time":"2026-09-20T00:00:00Z","event":"status_changed","id":"ui.equipment.tooltip","from":"UNMAPPED","to":"PARTIAL","reason":"equipment panel work exists but 40250 UI lifecycle and data-source equivalence remains open"}
{"time":"2026-09-20T00:00:00Z","event":"test_baseline","id":"movement.keyboard.motion","result":"PASS","tests":["project/test_wasd_steering_parity.gd","project/test_no_auto_move_regression.gd"],"reason":"covered WASD priority, rapid switching, input cleanup, and no-auto-move regressions pass"}
{"time":"2026-09-20T00:00:00Z","event":"test_baseline","id":"combat.death.exp_drop","result":"FAIL","tests":["project/mob_death_drop_test.gd"],"reason":"pickup ownership assertion fails; test process exits non-zero despite contradictory final summary"}
{"time":"2026-09-20T00:00:00Z","event":"test_baseline","id":"skill.cast.effect_timing","result":"FAIL","tests":["project/combat_fx_test.gd"],"reason":"restart-here UI/command assertions fail in the mixed test"}
{"time":"2026-09-20T00:00:00Z","event":"test_baseline","id":"ui.equipment.tooltip","result":"PASS","tests":["project/view_equipment_ui_test.gd"],"reason":"dialog geometry, slot mapping, shared tooltip and single-panel assertions pass"}
{"time":"2026-09-20T00:00:00Z","event":"fix_applied","id":"skill.cast.effect_timing","result":"PASS","files":["extension/src/net/entity_store.cpp","extension/tests/net_state_queue_test.cpp"],"reason":"matched 40250 eFunc & FUNC_SKILL walk-then-act behavior; near and far skill state regression cases pass"}
{"time":"2026-09-20T00:00:00Z","event":"fix_applied","id":"combat.death.exp_drop","result":"PASS","files":["extension/src/net/entity_store.cpp","extension/src/net/classic/classic_parser.cpp","extension/src/net/m2_client.cpp","project/net_play.gd","project/mob_death_drop_test.gd"],"reason":"preserved authoritative POINT_EXP.amount for experience feedback and corrected the local-owner drop fixture; combat/death/drop tests pass"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"combat.death.exp_drop","result":"PASS","tests":["/tmp/metin2-build-ext/extension/net_state_queue_test","project/mob_death_drop_test.gd","project/combat_fx_test.gd","project/combat_parity_test.gd","project/playable_combat_test.gd","project/net_world_vis_test.gd"],"reason":"native state/experience regression and Godot combat/death/drop suites pass"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"skill.cast.effect_timing","result":"PASS","tests":["/tmp/metin2-build-ext/extension/net_state_queue_test","project/skill_test.gd","project/netplay_test.gd","project/combat_parity_test.gd","project/combat_fx_test.gd"],"reason":"skill validation, state timing, combat effects, and network-play suites pass"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"network.login.phase_flow","result":"PARTIAL","files":["extension/src/net/m2_client.cpp","extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_parser.cpp","audit/contracts/network.login.phase-flow.md"],"reason":"successful phase mapping is located, but failure cleanup, timeout/reconnect, direct-enter ordering, and optional protocol branches are not yet proven equivalent"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"movement.keyboard.motion","result":"PARTIAL","files":["project/player_controller.gd","project/net_play.gd","project/net_world.gd","audit/contracts/movement.keyboard-motion.md"],"reason":"WASD regressions pass, but event-to-motion timing, fixed-destination versus continuous movement units, blocked-motion recovery, and packet order remain unverified"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"ui.equipment.tooltip","result":"PARTIAL","files":["project/ui/inventory_ui.gd","project/ui/shop_ui.gd","project/ui/ui_manager.gd","audit/contracts/ui.equipment-tooltip.md"],"reason":"inventory and shop still set native tooltip_text while also showing the shared custom tooltip, so the global single-panel rule is not yet satisfied"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"skill.cast.effect_timing","result":"PARTIAL","files":["project/net_world.gd","project/ui/player_view.gd","project/fx/skill_fx.gd","audit/contracts/skill.cast-effect-timing.md"],"reason":"FUNC_SKILL state timing is fixed, but motion loop count, moving-skill flag, skill grade, and resource-driven event timing are not yet carried through the visual path"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"ui.equipment.tooltip","result":"PASS","tests":["project/view_equipment_ui_test.gd","project/item_tooltip_test.gd"],"reason":"view-equipment singleton and tooltip regression tests pass; inventory/shop native tooltip duplication remains an audit finding"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"movement.keyboard.motion","result":"PASS","tests":["project/test_wasd_steering_parity.gd","project/test_no_auto_move_regression.gd"],"reason":"WASD priority, rapid switching, upright rotation, input cleanup, and no-auto-move regressions pass"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"network.login.phase_flow","result":"PARTIAL","tests":["project/app_flow_lifecycle_test.gd"],"reason":"single lifecycle-owner test passes; live socket login, timeout, reconnect, and direct-enter packet order were not run"}
{"time":"2026-09-20T00:00:00Z","event":"inventory_initialized","result":"PASS","contracts_added":40,"total_contracts":45,"files":["audit/contracts/function-inventory.md","audit/manifest.json"],"reason":"expanded the audit ledger from five reported behaviors to a complete 40250 runtime-function inventory across lifecycle, network, world, movement, combat, skills, items, social, quests, rendering, resources, audio, UI, and release domains"}
{"time":"2026-09-20T00:00:00Z","event":"inventory_normalized","result":"PASS","files":["audit/manifest.json","audit/contracts/ui.equipment-tooltip.md","audit/contracts/skill.cast-effect-timing.md"],"reason":"resolved abbreviated source paths to existing repository files and removed unavailable migration-script paths from the 40250 source evidence"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"lifecycle.bootstrap_phase_host","result":"PARTIAL","files":["project/client_main.gd","project/app_flow.gd","project/app_lifecycle.gd","extension/src/net/m2_client.cpp","audit/contracts/lifecycle.bootstrap-phase-host.md"],"reason":"startup and main phase ownership are mapped, but DEAD/close handling, Loading cleanup order, background semantics, and explicit Destroy-equivalent cleanup are not 1:1"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"network.character_select.create_delete","result":"PARTIAL","files":["extension/src/net/classic/classic_parser.cpp","extension/src/net/classic/classic_session.cpp","audit/contracts/network.character-select.md"],"reason":"character CRUD and direct-enter paths are present, but empire state timing, private-code boundary, UTF-8 versus locale truncation, event order, and direct-enter packet path differ or lack proof"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"network.packet_dispatch_protocol","result":"PARTIAL","files":["extension/src/net/classic/classic_stream.cpp","extension/src/net/classic/classic_parser.cpp","extension/src/net/classic/wire_classic.h","audit/contracts/network.packet-dispatch.md"],"reason":"framing is implemented, but one-pump burst dispatch, missing phase allowlists, zero-padding scope, and unknown/known-unhandled packet side effects differ from 40250"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"network.security_encoding","result":"PARTIAL","files":["extension/src/net/classic/classic_stream.cpp","extension/src/net/classic/classic_cipher.cpp","extension/src/net/text_codec.h","audit/contracts/network.security-encoding.md"],"reason":"handshake, sequence, DH2/CTR and version branches are mapped, but locale byte encoding, optional security branches, clock ownership, and real wire interop are not equivalent/proven"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"network.reconnect_warp","result":"PARTIAL","files":["extension/src/net/m2_client.cpp","extension/src/net/classic/classic_session.cpp","project/ui/reconnect_ui.gd","audit/contracts/network.reconnect-warp.md"],"reason":"GC_WARP is close to the reference path, but generic reconnect creates a new session and loses selected-slot/direct-enter state; cleanup, timeout, and duplicate reconnect guards remain different"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"network.error_timeout_server_state","result":"PARTIAL","files":["project/net/channel_status.gd","project/net/serverinfo.gd","project/app_flow.gd","audit/contracts/network.error-timeout-server-state.md"],"reason":"auth/channel/fallback flows exist, but main connection deadline is unproven and partial channel records can finish early; notification and recovery order differs"}
{"time":"2026-09-20T00:00:00Z","event":"test_baseline","result":"PENDING","files":["audit/contracts/lifecycle.bootstrap-phase-host.md","audit/contracts/network.character-select.md","audit/contracts/network.packet-dispatch.md","audit/contracts/network.security-encoding.md","audit/contracts/network.reconnect-warp.md","audit/contracts/network.error-timeout-server-state.md"],"reason":"contract-specific automatic tests are not yet complete; existing native tests will be rerun as regression evidence before the next implementation step"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","result":"PASS","tests":["build/extension/net_classic_stream_test","build/extension/net_classic_wire_test","build/extension/net_classic_session_test","build/extension/net_classic_cipher_test","build/extension/net_classic_encstream_test","build/extension/net_text_codec_test","project/app_flow_lifecycle_test.gd","project/char_create_delete_test.gd"],"reason":"existing network framing/session/cipher/text and lifecycle/character UI regressions pass; these are baseline tests only and do not close the documented parity gaps"}
{"time":"2026-09-20T00:00:00Z","event":"fix_applied","id":"network.character_select.create_delete","result":"PASS","files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.character-select.md"],"reason":"aligned character-delete private-code serialization with ClientVS22 strncpy(PRIVATE_CODE_LENGTH-1), including oversized input truncation and fixed-buffer terminator coverage"}
{"time":"2026-09-20T00:00:00Z","event":"fix_applied","id":"network.error_timeout_server_state","result":"PASS","files":["project/net/channel_status.gd","project/channel_status_test.gd","audit/contracts/network.error-timeout-server-state.md"],"reason":"buffered non-classic channel-status response bodies across TCP fragments and rejected invalid counts before completion"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"network.character_select.create_delete","result":"PASS","tests":["build/extension/net_classic_session_test","project/char_create_delete_test.gd"],"reason":"character delete serialization, classic session flow, and character UI regression tests pass"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"network.error_timeout_server_state","result":"PASS","tests":["project/channel_status_test.gd"],"reason":"classic/non-classic channel request and response parsing pass, including a response split inside a 3-byte channel record"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","result":"PASS","tests":["build/extension/net_classic_wire_test","build/extension/net_classic_stream_test","build/extension/net_classic_session_test","build/extension/net_classic_cipher_test","build/extension/net_classic_encstream_test","build/extension/net_text_codec_test","project/channel_status_test.gd","project/app_flow_lifecycle_test.gd","project/char_create_delete_test.gd"],"reason":"rebuilt and reran the affected classic network, channel-status, lifecycle, and character-selection regression suites after the two parity fixes"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"world.reset_cleanup","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseLoading.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/NetworkActorManager.cpp","project/game_scene.gd","project/net_world.gd","project/fly_object.gd","extension/src/net/entity_store.cpp","audit/contracts/world.reset-cleanup.md"],"reason":"Loading 清理链已核对;当前实现曾遗漏网络飞行/目标/特效 cue 与活动弹道/爆点跨图清理,旧地图释放顺序和退出 Destroy 仍不等价"}
{"time":"2026-09-20T00:00:00Z","event":"fix_applied","id":"world.reset_cleanup","result":"PASS","files":["project/fly_object.gd","project/net_world.gd","extension/src/net/entity_store.cpp","extension/tests/net_entity_test.cpp","project/fly_reset_test.gd","audit/contracts/world.reset-cleanup.md"],"reason":"按 40250 Loading 的 DeleteAllInstances 边界清理飞行、飞行目标、特效 cue、活动弹道、弹道视觉和爆点视觉,并加入原生/Godot 回归测试"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"world.map_load_transition","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/GameLib/MapManager.cpp","extension/src/metin2_world.cpp","project/game_scene.gd","audit/contracts/world.map-load-transition.md"],"reason":"确认当前跨图路径先构造并加载新 world、再 queue_free 旧 world,与 40250 Leave/Clear -> Load/Enter 顺序不同;失败、中断、重复 warp 和 streaming 边界尚未完成自动验证"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"world.entity_spawn_state_sync","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/NetworkActorManager.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameActor.cpp","extension/src/net/entity_store.cpp","project/net_world.gd","audit/contracts/world.entity-spawn-state-sync.md"],"reason":"Actor 数据层与场景层调用链已建立,但 Add/Info/Update/Delete/VID 重用、主 VID 切换、模型升级和延迟节点释放仍缺完整顺序证明"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"world.reset_cleanup","result":"PASS","tests":["build/extension/net_entity_test","build/extension/net_state_queue_test","project/fly_reset_test.gd"],"reason":"map reset 清理实体/地面/目标/飞行/特效网络队列,并确认活动弹道与爆点视觉在 Godot 场景中全部回收"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"movement.click_collision","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInputMouse.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInput.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseMovement.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseBattle.cpp","project/player_controller.gd","project/netplay.gd","audit/contracts/movement.click-collision.md"],"reason":"点地优先级、预约、移动 gate 和点击特效已有对应实现;Actor 碰撞仍使用固定半径近似,缺少 40250 的 MSM 碰撞球、逐碰撞调整和第二次碰撞停止等价证明"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"movement.click_collision","result":"PASS","tests":["project/player_move_test.gd","project/movement_parity_test.gd","project/netplay_test.gd","project/test_click_target_effect_parity.gd"],"reason":"现有点地、预约、阻挡、WASD/移动技能、交互预约和点击特效回归测试通过;合同仍因真实碰撞几何和完整鼠标绑定矩阵保持 PARTIAL"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"combat.attack_combo_damage","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseBattle.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceBattle.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerEventHandler.cpp","project/net_play.gd","project/game_scene.gd","audit/contracts/combat.attack-combo-damage.md"],"reason":"普攻/连击/hit window/击退/弓箭 FLY 主链已映射;发现待发 CG_SHOOT 队列未在 world reset 清理,且本地资源 fallback 与真实服务端伤害闭环仍不等价"}
{"time":"2026-09-20T00:00:00Z","event":"fix_applied","id":"combat.attack_combo_damage","result":"PASS","files":["project/game_scene.gd","project/gamescene_test.gd","audit/contracts/combat.attack-combo-damage.md"],"reason":"按旧 Actor/Loading 生命周期清空待发弓箭 FLY/CG_SHOOT 队列,避免换图后新动作消费旧地图攻击事件"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"combat.attack_combo_damage","result":"PASS","tests":["project/combat_fx_test.gd","project/combat_parity_test.gd","project/gamescene_test.gd","build/extension/net_state_queue_test"],"reason":"连击/命中窗/击退/弓箭时序和 scene reset regression 通过;合同仍因资源 fallback、鼠标状态 owner 和服务端伤害闭环保持 PARTIAL"}
{"time":"2026-09-20T00:00:00Z","event":"test_correction","id":"combat.attack_combo_damage","result":"PASS","tests":["project/gamescene_test.gd"],"reason":"修正 typed Array 测试注入方式并隔离未初始化音频淡出后,world reset 的 pending CG_SHOOT 清理断言已实际执行并通过"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"world.reset_cleanup","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","project/net_play.gd","project/game_scene.gd","project/gamescene_test.gd"],"reason":"CPythonPlayer::Clear 对应的 NetPlay 动作/预约/命中窗/击退同步状态没有统一 Loading reset 入口,存在跨图残留风险"}
{"time":"2026-09-20T00:00:00Z","event":"fix_applied","id":"world.reset_cleanup","result":"PASS","files":["project/net_play.gd","project/game_scene.gd","project/gamescene_test.gd","audit/contracts/world.reset-cleanup.md"],"reason":"新增 NetPlay.clear_for_map_change 并由 GameScene world_reset 调用,清理 Actor 动作、目标、预约、连击、命中窗、击退同步、技能/钓鱼门和经验基线"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"world.reset_cleanup","result":"PASS","tests":["project/gamescene_test.gd"],"reason":"场景级断言实际验证 pending CG_SHOOT、NetPlay 主 VID/目标/预约、攻击窗口和 victim sync queue 均在 world reset 后清空"}
{"time":"2026-09-20T00:00:00Z","event":"fix_applied","id":"world.reset_cleanup","result":"PASS","files":["project/net_play.gd","project/gamescene_test.gd"],"reason":"NetPlay map reset 入口同时调用 PlayerController.stop,清除旧点地目标和按键移动状态,防止换图后角色沿旧目标自动移动"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"item.inventory_equipment_state","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/GameType.h","extension/src/net/classic/classic_parser.cpp","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","project/ui/inventory_ui.gd","audit/contracts/item.inventory-equipment-state.md"],"reason":"完整核对 Set/Del/Update、deprecated 20 号包、装备/扩展槽、socket/属性和 UI 刷新;发现 outbound item cell 只做整数宽度检查、有效空槽 Update 被错误丢弃,装备操作行动门和 ItemManager 失败分支仍未等价"}
{"time":"2026-09-20T00:00:00Z","event":"fix_applied","id":"item.inventory_equipment_state","result":"PASS","files":["extension/src/net/net_bounds.h","extension/src/net/m2_client.cpp","extension/src/net/entity_store.cpp","extension/tests/net_bounds_test.cpp","extension/tests/net_entity_test.cpp","audit/contracts/item.inventory-equipment-state.md"],"reason":"按 ClientVS22 TItemPos::IsValidCell 补齐 inventory/equipment/dragon-soul/belt cell 域校验,并让有效空槽也接受 GC_ITEM_UPDATE 的 count/socket/attribute 更新"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"item.inventory_equipment_state","result":"PASS","tests":["build/extension/net_bounds_test","build/extension/net_entity_test","build/extension/net_classic_session_test","project/inventory_ui_test.gd","project/equip_model_test.gd"],"reason":"物品槽位边界、实体物品状态、40250 经典物品包、背包 UI 和装备模型回归测试通过;合同仍因 native 行动门、资源失败分支和完整 Loading 重建保持 PARTIAL"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"movement.keyboard.motion","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInputKeyboard.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInput.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseMovement.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceMotion.cpp","project/player_controller.gd","project/net_play.gd","project/net_world.gd","audit/contracts/movement.keyboard-motion.md"],"reason":"W/S、A/D、八方向优先级、失焦清理和停止时序已逐分支定位;当前端已能防止自动移动和快速反向翻转,但固定 300 像素目标/根运动、motion event 事件源、同步与动作锁门、相机副作用和真实模型链仍与 40250 存在材料差异"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"movement.keyboard.motion","result":"PASS","tests":["project/test_wasd_steering_parity.gd","project/test_no_auto_move_regression.gd","project/netplay_test.gd","project/movement_parity_test.gd","project/keyboard_motion_timeline_test.gd"],"reason":"键盘方向优先级、失焦/加载期按键清理、移动/停止、NetPlay 0/300/100ms 节流和 W/S 时间线回归测试通过;合同保持 PARTIAL,因为动作资源根运动和完整禁止移动/恢复分支尚未等价证明"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"movement.remote_sync_state","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBase.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/NetworkActorManager.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameActor.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseHandShake.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceSync.cpp","extension/src/net/entity_store.cpp","extension/src/net/classic/classic_parser.cpp","project/net_world.gd","audit/contracts/movement.remote-sync-state.md"],"reason":"远端 GC_MOVE 队列、70/30 EMA、服务器帧释放、WAIT/MOVE/COMBO/ATTACK/MOB_SKILL/SKILL 阈值、根运动推进和死亡/击倒挂队已逐分支核对;发现 FUNC_EMOTION/不可取消技能/表情锁门、TEMP_Push 纠偏物理、动作 arg 和无模型 fallback 与 40250 仍有材料差异"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"movement.remote_sync_state","result":"PASS","tests":["build/extension/net_state_queue_test","build/extension/net_entity_test","project/netplay_test.gd","project/movement_parity_test.gd"],"reason":"远端状态队列的时钟门、阈值分支、技能位、死亡/击倒挂起、FIFO、根运动和 duration fallback 回归通过;合同保持 PARTIAL,未将单元测试通过误报为完整 40250 等价"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"resource.pack_locale_proto","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/EterPack/EterPackManager.cpp","../40250/Server Client TMP4/ClientVS22/source/EterPack/EterPackCursor.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPackModule.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLocale/StringCodec.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ItemManager.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNonPlayer.cpp","extension/src/pack/eterpack.cpp","extension/src/pack/pack_mount.cpp","formats/asset_resolver.cpp","project/asset_root.gd","project/locale.gd","extension/src/proto/proto.cpp","audit/contracts/resource.pack-locale-proto.md"],"reason":"proto fourcc/stride/CLZO、MSA/MSM、连击表和路径归一化已有实现与格式测试;但当前主链使用 loose/assets.zip/PCKcustom epk 与 40250 EterPack 不互读,AssetSource 未统一接入,locale code page、完整 pack overlay/cache 和失败回退未等价"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"resource.pack_locale_proto","result":"PASS","tests":["build/extension/pack_roundtrip_test","build/extension/proto_test","build/extension/proto_item_layout_test","build/formats/formats_msm_test","build/formats/formats_msa_test","build/formats/formats_combo_table_test","build/formats/formats_map_test","project/test_chinese_locale.gd","project/skill_test.gd"],"reason":"当前 pack roundtrip、proto 真实/合成字段、MSM/MSA/连击表/地图格式、中文 locale 和技能资源测试通过;proto_test 在当前仓库没有 en proto 时按既有约定 skippackage_render_test 因需要导出包生命周期未计入。本合同仍保持 PARTIAL,因为测试覆盖的是当前格式与 happy path,尚未证明 40250 EterPack/编码/失败分支等价"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"world.terrain_water_collision","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoor.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/AreaTerrain.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoorWater.cpp","../40250/Server Client TMP4/ClientVS22/source/PRTerrainLib/Terrain.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/AttributeInstance.cpp","extension/src/metin2_world.cpp","formats/terrain_files.cpp","formats/terrain_mesh.cpp","extension/src/water_builder.cpp","project/player_controller.gd","project/net_world.gd","audit/contracts/world.terrain-water-collision.md"],"reason":"地形插值、桥梁/平台对象高度、ATTRIBUTE_BLOCK/WATER、水深 alpha、30帧水纹和共享水面扰动已逐分支核对;发现静态对象 ray picking 未接入、water id 到具体层高未进入钓鱼目标 Z、高半字节属性和 streaming/碰撞清理边界仍与 40250 有材料差异"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"world.terrain_water_collision","result":"PASS","tests":["build/formats/formats_map_test","project/test_bridge_height_parity.gd","project/test_all_map_height_probe.gd","project/water_reference_test.gd","project/fishing_water_test.gd","project/test_click_target_effect_parity.gd","project/player_move_test.gd","project/test_skill_ground_fix.gd"],"reason":"地图格式、A1/C1 桥面与河床回退、水面四角深度/浅滩、真实水属性/钓鱼方向、点击/弹道、移动阻挡和技能贴地回归通过;formats_map_test 在 M2_ASSETS 未设置时跳过 live A1 断言,点击地面段使用 mock world,因此不将测试通过误报为完整 40250 ray picking 等价"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"combat.death.exp_drop","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseBattle.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstance.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","extension/src/net/classic/classic_parser.cpp","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","project/net_play.gd","project/net_world.gd","project/ui/ground_items.gd","project/ui/death_ui.gd","audit/contracts/combat.death-exp-drop.md"],"reason":"GC_DAMAGE/GC_DEAD/POINT_EXP.amount/GC_CREATE_FLY/ground add-del 的服务端权威主链已逐分支核对;发现主角死亡未统一停止 PlayerController/清自动攻击,POINT_* point effect/金币和完整 GameOver 分支未等价,重复/乱序/复活/跨图清理与真实包序仍缺证据"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"combat.death.exp_drop","result":"PASS","tests":["build/extension/net_state_queue_test","project/mob_death_drop_test.gd","project/combat_parity_test.gd","project/playable_combat_test.gd","project/gamescene_test.gd"],"reason":"POINT_EXP amount 累计/一次消费、死亡目标清理、掉落归属/坐标/拾取、攻击锁/伤害/击退、技能前置和地图 reset 回归通过;测试仍未覆盖真实服务端攻击→死亡→经验→掉落包序及主角死亡后的输入门,因此合同保持 PARTIAL"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"lifecycle.bootstrap_phase_host","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonApplication.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonApplicationProcedure.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStream.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseLoading.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/MSWindow.cpp","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_session.cpp","project/app_flow.gd","project/app_lifecycle.gd","project/game_scene.gd","project/ui/death_ui.gd","audit/contracts/lifecycle.bootstrap-phase-host.md"],"reason":"启动/每帧、阶段 owner、Loading、DEAD/CLOSE、窗口焦点/后台和 Destroy 调用链已逐分支核对;发现 PHASE_DEAD 未产生 DeathUI 监听的 dead phasePHASE_CLOSE 进入 Failed 而非 40250 Login,普通 Loading/重连缺统一 resetclose_requested 无消费者,模型等待期间存在主动 net_poll 重入点,显式总销毁顺序未等价"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"lifecycle.bootstrap_phase_host","result":"PASS","tests":["project/app_flow_lifecycle_test.gd"],"reason":"验证 AppFlow 单一 AppLifecycle、登录/游戏切换、游戏断线保留场景、原槽位重进和显式槽位边界;该测试未覆盖固定每帧顺序、Loading 清理、DEAD/CLOSE、窗口关闭和最终销毁,因此合同保持 PARTIAL"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"lifecycle.bootstrap_phase_host","result":"PARTIAL","files":["project/client_main.gd","project/app_flow.gd","project/login.gd","project/app_lifecycle.gd","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_session.cpp","audit/contracts/lifecycle.bootstrap-phase-host.md"],"reason":"本轮补核了主入口与旧 login.gd 入口:client_main -> AppFlow 与 login.gd 各自创建 AppLifecycle/M2Client/GameScene,单一生命周期属主只在主入口成立;同时确认 M2Client._process/协程主动 net_poll、PHASE_DEAD/CLOSE、普通 Loading reset、close consumer 和最终 Destroy 顺序仍未与 40250 统一,合同保持 PARTIAL,未修改实现"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"lifecycle.bootstrap_phase_host","result":"PASS","tests":["project/app_flow_lifecycle_test.gd","project/gamescene_test.gd","project/channel_status_test.gd"],"reason":"AppFlow 单生命周期、断线原槽位重进、场景装配/world reset 和频道状态回归退出码通过;gamescene_test 使用不存在地图验证平地 fallback,不能证明真实 40250 Loading/Destroy;所有测试均未覆盖旧 login.gd 入口、固定每帧顺序、DEAD/CLOSE、窗口 close、重复销毁或真实 socket 包序,因此合同保持 PARTIAL"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"network.login.phase_flow","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/AccountConnector.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseHandShake.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseLogin.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseSelect.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseLoading.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStream.cpp","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_stream.cpp","extension/src/net/classic/classic_parser.cpp","extension/src/net/auth_client.h","project/app_flow.gd","audit/contracts/network.login.phase-flow.md"],"reason":"认证、握手、登录、角色列表、DirectEnter、Loading、EnterGame 和 GAME 主链已逐分支核对;发现当前密码仍保存在 session/config,登录失败压成 Failed 并断流,PHASE_CLOSE 不回 Login,可选 Matrix/Passpod/Hybrid 分支不支持,连接/握手 deadline、重复进入和真实服务端包序仍缺等价证据"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"network.login.phase_flow","result":"PASS","tests":["build/extension/net_classic_session_test","build/extension/net_classic_stream_test","build/extension/net_loopback_test","project/app_flow_lifecycle_test.gd"],"reason":"ClassicSession/ClassicStream framing、握手、认证到游戏 loopback、角色选择/DirectEnter 和 AppFlow 状态回归通过;测试覆盖成功主路径,未覆盖所有失败/可选安全包/timeout/密码清理/真实 40250 包序,因此合同保持 PARTIAL"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"network.character_select.create_delete","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/Packet.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStream.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseLogin.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseSelect.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","extension/src/net/classic/wire_classic.h","extension/src/net/classic/classic_parser.cpp","extension/src/net/classic/classic_session.cpp","extension/src/net/m2_client.cpp","project/app_flow.gd","project/ui/char_select_screen.gd","audit/contracts/network.character-select.md"],"reason":"角色列表、3/4 槽固定数组、帝国选择、普通选人、创建/删除/改名、DirectEnter 和异常清理已逐分支核对;发现 3 槽成功包当前缩成 3 个 vector 元素、帝国本地写入时点不同、创建越界/slot 3 响应不同、改名未命中 PID 不产生参考错误码 100、DirectEnter 在 PHASE_SELECT 可能额外发送 CG_PLAYER_SELECTlocale codepage 与 UTF-8 仍不等价"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"network.character_select.create_delete","result":"PASS","tests":["build/extension/net_classic_session_test","build/extension/net_loopback_test","project/char_create_delete_test.gd","project/test_intro_select_parity.gd"],"reason":"4 槽角色列表、CRUD loopback、删除码边界、DirectEnter 目标连接和 Godot 选人页回归通过;测试没有覆盖 3 槽固定第 4 槽、locale 编码、改名未命中 PID、DirectEnter PHASE_SELECT 包序列和中断清理,因此合同保持 PARTIAL"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"network.packet_dispatch_protocol","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/Packet.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStream.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseLogin.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseSelect.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseLoading.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/NetPacketHeaderMap.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/NetStream.cpp","extension/src/net/classic/classic_stream.cpp","extension/src/net/classic/classic_parser.cpp","extension/src/net/classic/wire_classic.h","audit/contracts/network.packet-dispatch.md"],"reason":"40250 主表 117 项(106 静态、13 动态)、CheckPacket、四阶段 allowlist、WHISPER 两段式消费、leading zero、单 tick 分派和错误清理已核对;发现当前统一 parser 缺少 phase gate,一次 dispatch drain burstWHISPER 被归入 dynamicQUEST_INFO/GUILD 重新计算边界,unknown/handler false/underflow 的断流副作用不同,完整别名尺寸矩阵和边界证据仍待补齐"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"network.packet_dispatch_protocol","result":"PASS","tests":["build/extension/net_classic_stream_test","build/extension/net_classic_wire_test"],"reason":"现有 ClassicStream framing、ping/sequence、静态/动态、分片、未知 header 和 handler false 回归通过;未覆盖 117 项生成矩阵、四阶段 allowlist、WHISPER 两段式边界和 40250 单 tick/burst 语义,因此合同保持 PARTIAL"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"network.reconnect_warp","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStream.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseLoading.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/NetworkActorManager.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/NetStream.cpp","extension/src/net/classic/classic_session.cpp","extension/src/net/m2_client.cpp","extension/src/net/entity_store.cpp","project/game_scene.gd","project/net_play.gd","project/net_world.gd","project/app_flow.gd","project/ui/reconnect_ui.gd","audit/contracts/network.reconnect-warp.md"],"reason":"GC_WARP、ConnectGameServer、同一 stream 的 transport clear、Loading/Game leave 清理、generic reconnect 和 UI retry 已逐分支核对;发现 GC_WARP classic 主链接近参考但 external world_reset 时序不同,generic reconnect 销毁 ClassicSession 后清空 selected slot/direct-enter,依赖 char_list 回放补偿,连接 deadline/in-flight guard/重复 warp 和旧会话竞态仍无等价证据"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"network.reconnect_warp","result":"PASS","tests":["build/extension/net_classic_session_test","project/app_flow_lifecycle_test.gd","project/gamescene_test.gd","project/p9_test.gd"],"reason":"direct-enter/GC_WARP endpoint 与 slot/login key 保留、断线后 UI 原槽位回放、world_reset 清理、地图 warp 相关回归通过;未覆盖 M2Client generic reconnect native 状态、connect deadline、重复重试 guard 和真实旧/新 socket 竞态,因此合同保持 PARTIAL"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"network.security_encoding","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseHandShake.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseLogin.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseSelect.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/AccountConnector.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/NetStream.cpp","../40250/Server Client TMP4/ClientVS22/source/EterBase/cipher.cpp","../40250/Server Client TMP4/ClientVS22/source/EterBase/tea.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLocale/StringCodec.cpp","extension/src/net/classic/classic_stream.cpp","extension/src/net/classic/classic_cipher.cpp","extension/src/net/classic/sequence_table.h","extension/src/net/classic/wire_classic.h","extension/src/net/text_codec.h","extension/src/net/secure_cipher.cpp","audit/contracts/network.security-encoding.md"],"reason":"已逐分支核对初始/后续 handshake、全局 server timer 与 HANDSHAKE_OK 二次校准、32768 sequence/bSeq、DH2/CTR completed 前后状态、flush 时加密、legacy TEA、HybridCrypt keys/SDB、Panama pack、HS/XTrap、Windows locale codepage 与 fixed stringDH2/CTR 局部公式接近但当前缺少全局 clock 校准、legacy/optional 资源链、真实 codepage 和完整互操作证据,合同保持 PARTIAL,未修改实现"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"network.security_encoding","result":"PASS","tests":["build/extension/net_classic_cipher_test","build/extension/net_classic_encstream_test","build/extension/net_text_codec_test"],"reason":"DH2/CTR 双端 round-trip、stream handshake/key agreement/completed/已缓冲密文、sequence trailer 和当前 UTF-8 定长截断回归通过;这些测试未覆盖 40250 全局 timer、HANDSHAKE_OK 二次校准、legacy TEA、HybridCrypt/Panama/anti-cheat、真实 Windows codepage 和 reference sequence hash,因此合同保持 PARTIAL"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"world.entity_spawn_state_sync","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/NetworkActorManager.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameActor.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonCharacterManager.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBase.cpp","extension/src/net/classic/classic_parser.cpp","extension/src/net/classic/classic_parser.h","extension/src/net/entity_store.cpp","extension/src/net/entity_store.h","extension/src/net/m2_client.cpp","project/net_world.gd","project/game_scene.gd","project/net_play.gd","audit/contracts/world.entity-spawn-state-sync.md"],"reason":"已逐分支核对旧 Add/AdditionalInfo、Add2、Update、Delete、主 VID、VID 重用和可见性;发现 generic unknown AdditionalInfo 会创建部分 EntityAdd/Add2/Update 的 state/affect 等字段遗漏,Add2 缺隐身种族过滤,Add2 事件被拆分,同 VID 重用无条件保留旧坐标,主 VID 清理范围和 pending stale/淡出竞态仍未等价,合同保持 PARTIAL,未修改实现"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"world.entity_spawn_state_sync","result":"PASS","tests":["build/extension/net_entity_test","build/extension/net_classic_session_test","project/net_world_vis_test.gd","project/gamescene_test.gd"],"reason":"现有 EntityStore、classic Add/AdditionalInfo/Delete、可见性、远端节点和场景回归通过;测试没有覆盖 Add2 完整字段/隐身过滤、generic unknown AdditionalInfo、state/affect 全路径、Delete 后迟到包、同 VID mount 条件重用和主 VID 全量清理,因此合同保持 PARTIAL"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"world.map_load_transition","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/GameLib/MapManager.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoor.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoorLoad.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoorUpdate.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/AreaLoaderThread.cpp","extension/src/metin2_world.cpp","extension/src/metin2_world.h","project/game_scene.gd","project/net_play.gd","project/net_world.gd","project/app_flow.gd","audit/contracts/world.map-load-transition.md"],"reason":"已逐文件核对 LoadMap 的 Leave/LoadProperty/Load/Environment/Enter、玩家坐标驱动的 3x3 区域、area loader queue、延迟回收、Unload name 校验和当前 Metin2World/GameScene 的 warp/reset/streaming;发现跨图先建新 World 后 queue_free 旧 World、缺图继续平地 fallback、Unload 无 map-name 校验、区域回收即时 queue_free、旧异步结果/generation 边界未等价,合同保持 PARTIAL,未修改实现"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"world.map_load_transition","result":"PARTIAL","tests":["project/gamescene_test.gd","project/p9_test.gd"],"reason":"GameScene fallback/装配/主角定位/world reset 与 warp signal、地图时间/小地图/天气回归通过;project/forest_map_render_test.gd 不是 SceneTree/MainLoop,直接启动会被 Godot 拒绝,需由其指定 runner 执行。现有测试未覆盖真实 Leave/Clear/Load/Enter、双 World、重复 warp、streaming 边界、碰撞和失败重试,因此合同保持 PARTIAL"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"item.inventory_equipment_state","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/GameType.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ItemManager.cpp","extension/src/net/entity_store.cpp","extension/src/net/classic/classic_parser.cpp","extension/src/net/classic/classic_session.cpp","extension/src/net/m2_client.cpp","project/ui/inventory_ui.gd","audit/contracts/item.inventory-equipment-state.md"],"reason":"本轮补核完整物品收包和操作链:40250 SetItemData 的 ItemManager 未知 vnum 拒绝、Set2 highlight、Update 的 SetItemCount/末尾 Refresh 双时序、IsEquipItemInSlot、__CanActMainInstance、交易/商店/攻击中门、PlayUseSound/PlayDropSound/SendSequence;当前 native store/发送路径缺资源拒绝、highlight、双刷新和行动状态/音效门,get_inventory 隐藏空槽 Update 字段,合同保持 PARTIAL,未修改实现"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"item.inventory_equipment_state","result":"PASS","tests":["build/extension/net_bounds_test","build/extension/net_entity_test","build/extension/net_classic_session_test","project/inventory_ui_test.gd","project/equip_model_test.gd","project/item_tooltip_test.gd","project/view_equipment_ui_test.gd"],"reason":"物品槽位边界、Set/Update/Del/socket/attribute、经典 20/21/25 帧、背包 UI、装备模型、tooltip 和单面板回归均退出码通过;view_equipment_ui_test 仍报告 5 个 ObjectDB 泄漏,且测试未覆盖未知 vnum、交易/商店/攻击中、音效、Set2 highlight、Update 双刷新、空槽 API 可见性和换图/断线重建,因此合同保持 PARTIAL"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"world.reset_cleanup","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStream.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseLoading.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/NetworkActorManager.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/FlyingObjectManager.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/EffectManager.cpp","extension/src/net/m2_client.cpp","extension/src/net/entity_store.cpp","project/game_scene.gd","project/net_play.gd","project/net_world.gd","project/fly_object.gd","project/ground_items.gd","project/bgm_director.gd","audit/contracts/world.reset-cleanup.md"],"reason":"已逐分支核对 SetLoadingPhase、RecvWarp、Player Clear、Actor/Flying/Effect 清理、EntityStore reset、world_reset、NetPlay/NetWorld/FlyObject/UI/BGM 清理和 disconnect;发现当前 reset 在 stage 变更前由 store 先清、依赖同步 signal + queue_free、没有统一 generation/断线 world_reset,旧 World 仍可能共存;screen_hp_bar_test 有 previously freed 访问,rendering_scenario_test 退出码 139,合同保持 PARTIAL,未修改实现"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"world.reset_cleanup","result":"PARTIAL","tests":["project/fly_reset_test.gd","project/screen_hp_bar_test.gd","project/rendering_scenario_test.gd","project/dungeon_state_test.gd","project/bgm_test.gd","project/gamescene_test.gd"],"reason":"fly reset、dungeon state、BGM、GameScene 回归退出码通过;screen_hp_bar_test 虽退出码 0 仍打印 previously freed 访问错误,rendering_scenario_test 报 failures=0 但退出码 139,故不能作为干净 PASS。尚未覆盖 GC_WARP/重连/close/dead 的完整顺序和延迟释放安全。"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"movement.click_collision","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInputMouse.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInputKeyboard.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseMovement.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceCollisionDetection.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoor.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/GameUtil.cpp","project/player_controller.gd","project/ui/mouse_controller.gd","project/hit_collision.gd","project/game_scene.gd","project/net_play.gd","project/ui/ground_items.gd","extension/src/metin2_world.cpp","audit/contracts/movement.click-collision.md"],"reason":"已逐分支核对 MBS_PRESS/MBS_CLICK、Smart item/actor/ground/screen 优先级、reservation、NEW_Goto/Stop、ATTRIBUTE_BLOCK、真实 MSM collision sphere、Avoid/BlockMovement 和 current ray/切线/xz 分轴推进;发现当前只实现左键 press 单击,缺 Smart hold 状态机,运行时 movable distance/碰撞球/对象 picking/BlockMovement 与参考不等价,合同保持 PARTIAL,未修改实现"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"movement.click_collision","result":"PARTIAL","tests":["project/player_move_test.gd","project/movement_parity_test.gd","project/netplay_test.gd","project/test_click_target_effect_parity.gd"],"reason":"Src/Dst、移动 gate、预约、转向阻尼、到达、切线碰撞、NetPlay click loop、点地/目标光圈/飞行物障碍回归通过;click/target/fly 测试仍报告 3 个 ObjectDB 泄漏和 1 个资源退出时仍在使用,且现有测试未覆盖 MBS_PRESS、多碰撞停止、MSM 骨骼球和对象 picking 边界,因此合同保持 PARTIAL"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"movement.remote_sync_state","result":"PASS","tests":["build/extension/net_state_queue_test","build/extension/net_entity_test","project/netplay_test.gd","project/movement_parity_test.gd"],"reason":"远端状态队列服务器帧门、70/30 EMA、WAIT/攻击/技能阈值、死亡/击倒挂起、FIFO、根运动/duration fallback、EntityStore 移动和当前 NetPlay 回归通过;这些测试仍未覆盖 FUNC_EMOTION 距离分支、不可取消技能/表情锁、TEMP_Push 纠偏物理、combo/skill arg 动作资源和真实 40250 时基,因此合同保持 PARTIAL"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"combat.attack_combo_damage","result":"PASS","tests":["project/combat_fx_test.gd","project/combat_parity_test.gd","project/playable_combat_test.gd","extension/tests/net_state_queue_test.cpp"],"reason":"攻击锁、连击、命中窗、defending sphere、击退/抗击倒、伤害表现、弓箭动作路径和状态包回归通过;未覆盖真实服务端伤害/死亡包序、鼠标 press/release owner、缺失动作资源与跨图攻击队列之外的完整清理,因此合同保持 PARTIAL"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"combat.death.exp_drop","result":"PASS","tests":["project/mob_death_drop_test.gd","project/combat_parity_test.gd","project/playable_combat_test.gd","build/extension/net_state_queue_test"],"reason":"怪物死亡目标/HP/名字清理、掉落坐标/owner/拾取/删除、经验增量累计和本地战斗边界回归通过;未覆盖主角 GC_DEAD 后停止输入/自动攻击、POINT_* 专门 effect、真实攻击→死亡→POINT_EXP→CREATE_FLY→掉落包序、重复死亡/复活/重连竞争,因此合同保持 PARTIAL"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"skill.cast.effect_timing","result":"PARTIAL","tests":["project/skill_test.gd","project/combat_fx_test.gd","project/test_skill_ground_fix.gd"],"reason":"技能表、技能 UI、施法锁、命中/特效和地形高度回归通过;project/test_full_skill_flow.gd 预加载不存在的 res://net_client_fake.gd,虽命令退出码为 0 实际是脚本解析失败,不能计为通过。仍未覆盖逐技能 MSA/MSE 关键帧、挂点/颜色/混合、动作循环/等级/移动技能参数、取消/死亡/重复施法和真实服务端结果包。"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"item.consumable_action","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerModule.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Packet.h","project/consumable_system.gd","project/item_split_system.gd","project/ui/quickbar.gd","project/ui/inventory_ui.gd","project/ui/shop_ui.gd","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_session.cpp","extension/src/net/entity_store.cpp","audit/contracts/item.consumable-action.md"],"reason":"已完成 40250 与当前端的快捷栏、物品使用、消耗品反馈、堆叠拆分和商店出售调用链对照。确认当前 native 协议基础存在,但 ConsumableSystem 未接入 ITEM_USE/ITEM_UPDATE/AFFECT/POINT/SPECIAL_EFFECT 权威反馈;ItemSplitSystem::split_item 直接改本地 Arrayquick_sell_item 直接加金币并清槽,均绕过服务端;quickbar 添加/删除/交换在请求后乐观修改状态,native 还缺 __CanActMainInstance、装备/交易/商店/攻击中门控、音效和 SendSequence 等参考副作用。合同保持 PARTIAL,未修改实现。"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"item.consumable_action","result":"PARTIAL","tests":["project/test_consumables_parity.gd","project/test_item_split_parity.gd","project/test_taskbar_quickslot_parity.gd","project/complex_item_drop_test.gd","project/netplay_test.gd"],"reason":"消耗品本地算法 36/36、物品拆分/本地快捷出售 19/19、快捷栏 UI 34/34、NetPlay 主循环通过;complex_item_drop_test 有 1 项购买模式卖出目标拒绝检查失败,quickbar 测试退出时有 91 个 CanvasItem RID、221 个 ObjectDB 对象和资源泄漏警告。这些测试未覆盖真实服务器确认、拒绝回滚、GC_ITEM_USE/UPDATE/AFFECT/POINT/SPECIAL_EFFECT 顺序、拆分 CG_ITEM_MOVE 和 SELL2 回包,因此不能标记 PASS。"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"item.drop_pickup","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonItem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInputMouse.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonTextTail.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ItemData.cpp","project/ui/ground_items.gd","project/net_play.gd","project/player_controller.gd","extension/src/net/classic/classic_parser.cpp","extension/src/net/classic/classic_session.cpp","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","audit/contracts/item.drop-pickup.md"],"reason":"已逐分支核对 ground add/owner/del、CreateItem、drop model/effect/sound/terrain/animation、TextTail、模型点选、20 像素走近预约、500ms pickup 节流、owner/party/anti-flag/observer 门控和拾取回包。当前端有基础状态、坐标、owner 标签、最近拾取和协议骨架,但使用通用 item_bag/BoxMesh 代替 CItemData drop model,缺 drop effect/sound/animation/法线;拾取只做 owner 名字判断,缺 ItemManager anti-flag/party/native action gate64px 投影点选也不等于模型 Intersect + TextTail Pick。合同保持 PARTIAL,未修改实现。"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"item.drop_pickup","result":"PARTIAL","tests":["project/test_ground_pickup_parity.gd","project/mob_death_drop_test.gd","project/p2b_test.gd","project/text_tail_arrange_test.gd","build/extension/net_entity_test","build/extension/net_classic_session_test"],"reason":"test_ground_pickup_parity、mob_death_drop_test、text_tail_arrange_test、net_entity_test、net_classic_session_test 通过;p2b_test 主断言通过但退出时有 2 个 ObjectDB 泄漏。现有测试未覆盖未知 vnum、实际 drop model/effect/sound、模型相交、party+anti-flag、native action gate、CG_ITEM_PICKUP 后完整 GC_DEL→ITEM_GET/ITEM_SET/UPDATE 包序和失败/乱序清理,因此合同保持 PARTIAL。"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"item.refine_socket_costume","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamModule.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerModule.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonItem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonItemModule.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameActor.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBase.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Packet.h","../40250/Server Client TMP4/ClientVS22/source/GameLib/ItemData.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ItemData.h","../40250/Server Client TMP4/Client/Eternexus/root/uirefine.py","../40250/Server Client TMP4/Client/Eternexus/root/uiinventory.py","../40250/Server Client TMP4/Server/metin2/src/server/game/src/char_item.cpp","../40250/Server Client TMP4/Server/metin2/src/server/game/src/item.cpp","../40250/Server Client TMP4/Server/metin2/src/server/game/src/item_attribute.cpp","../40250/Server Client TMP4/Server/metin2/server/share/conf/item_proto.txt","project/ui/refine_ui.gd","project/refine_effect_system.gd","project/item_attr_system.gd","project/item_enchant_system.gd","project/jewelry_socket_system.gd","project/costume_system.gd","project/costume_attr_transfer_system.gd","project/wardrobe_transmog_system.gd","project/ui/equip_model.gd","extension/src/net/m2_client.cpp","extension/src/net/m2_client.h","extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_session.h","extension/src/net/classic/classic_parser.cpp","extension/src/net/classic/wire_classic.h","extension/src/net/entity_store.cpp","extension/src/net/entity_store.h","audit/contracts/item.refine-socket-costume.md"],"reason":"已完成强化、镶嵌、属性、时装和外观换装的逐函数、协议、资源和状态链审计。确认 M2Client::refine 错误拒绝 40250 取消哨兵 255,255EntityStore 对旧版 59 字节 GC_REFINE_INFORMATION(95) 复用新版 60 字节结构并丢弃旧包;属性/镶嵌/时装 helper 主要直接修改本地 Dictionary/Array,未闭合 ItemManager→CG_ITEM_USE/ITEM_USE_TO_ITEM→GC_ITEM_UPDATE/POINT/AFFECT→actor/model 更新链;wardrobe/transmog 未在 40250 客户端中找到对应协议,标记为自定义扩展。合同保持 PARTIAL,未修改实现。"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"item.refine_socket_costume","result":"PARTIAL","tests":["project/test_refine_parity.gd","project/test_refine_effect_parity.gd","project/test_item_attr_parity.gd","project/test_item_enchant_manager_parity.gd","project/test_jewelry_socket_parity.gd","project/test_costume_system_parity.gd","project/test_costume_attr_transfer_parity.gd","project/test_wardrobe_transmog_parity.gd","build/extension/net_classic_session_test","build/extension/net_entity_test"],"reason":"refine UI 通过;强化效果 25/25、属性 28/28、附魔管理 36/36、首饰镶嵌 23/23、时装 23/23、时装属性 23/23、幻化 22/22 通过。上述脚本测试均主要验证本地 helper 或 fake client,未覆盖旧/新版 refine 包、255,255 取消包、真实服务器 item/point/affect/actor 回包、断线/乱序/回滚,因此合同不能标记 PASS。"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"npc.dialog_shop","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonShop.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamModule.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInput.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInputMouse.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Packet.h","../40250/Server Client TMP4/Client/Eternexus/root/uishop.py","../40250/Server Client TMP4/Client/Eternexus/root/uiprivateshopbuilder.py","../40250/Server Client TMP4/Client/Eternexus/root/uiinventory.py","../40250/Server Client TMP4/Client/Eternexus/root/playersettingmodule.py","project/npc_shop_system.gd","project/private_shop_system.gd","project/ui/shop_ui.gd","project/ui/private_shop_ui.gd","project/net_play.gd","project/net_world.gd","project/ui/quest_dialog.gd","extension/src/net/m2_client.cpp","extension/src/net/m2_client.h","extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_session.h","extension/src/net/classic/classic_parser.cpp","extension/src/net/classic/wire_classic.h","extension/src/net/entity_store.cpp","extension/src/net/entity_store.h","audit/contracts/npc.dialog-shop.md"],"reason":"已完成 NPC 点击、脚本对话、普通/多货架商店、买卖、个人商店招牌和摆摊提交的逐分支/协议/状态审计。确认 EntityStore 增量更新错误限制在 40 槽并只更新 tab 0;购买模式拖放仍可触发出售;个人商店招牌仅显示不可点击打开;自己的个人商店未按 shop VID 隐藏买卖;native 买卖缺 40250 动作门控和完整物品校验;live 路径仍存在硬编码库存/本地金币旁路。合同保持 PARTIAL,未修改实现。"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"npc.dialog_shop","result":"PARTIAL","tests":["project/test_npc_shop_parity.gd","project/test_npc_shop_flow.gd","project/test_npc_dialog_shop_ui_parity.gd","project/private_shop_ui_test.gd","project/test_private_shop_bundle_parity.gd","project/shop_rules_test.gd","project/p8_test.gd","project/complex_item_drop_test.gd","build/extension/net_classic_session_test","build/extension/net_entity_test"],"reason":"NPC 点击/距离/节流、普通和多货架本地 UI、脚本对话、摆摊编辑和基础 packet/store 测试通过或主断言通过;complex_item_drop_test 仍有购买模式拖放出售检查失败。现有测试主要使用 fake client/本地 helper,未覆盖 START_EX 的 40..119 增量更新、PC 招牌点击、自己商店分支、真实服务端买卖结果、错误/售罄/断线/乱序清理,因此合同不能标记 PASS。"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"social.chat_text_tail","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonChat.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonChat.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonTextTail.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonTextTail.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseEffect.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Packet.h","../40250/Server Client TMP4/Client/Eternexus/root/game.py","../40250/Server Client TMP4/Client/Eternexus/root/uiwhisper.py","../40250/Server Client TMP4/Client/Eternexus/root/localeInfo.py","../40250/Server Client TMP4/Client/Eternexus/root/colorInfo.py","project/chat_tail.gd","project/text_tail.gd","project/text_tail_arrange.gd","project/name_tail_layout.gd","project/ui/chat_ui.gd","project/whisper_chat_system.gd","project/net_world.gd","project/game_scene.gd","extension/src/net/entity_store.cpp","extension/src/net/entity_store.h","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_session.h","extension/src/net/classic/wire_classic.h","audit/contracts/social.chat-text-tail.md"],"reason":"已完成公共聊天、私聊、忽略、聊天气泡、名字/称号/等级/公会名尾标及文本布局的逐分支/协议/状态审计。确认 live 私聊会话未接入 M2Client.whisper_receivedsub==1/2 的 whisper mode 映射错误;公共频道颜色与 40250 不一致;无 VID notice/big notice、入站表情/跨帝国转换/辱骂过滤/延迟消息和未知角色忽略分支缺失;Godot 尾标使用 billboard 与宽度估算而非参考字体对象。合同保持 PARTIAL,未修改实现。"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"social.chat_text_tail","result":"PARTIAL","tests":["project/chat_test.gd","project/chat_tail_test.gd","project/text_tail_test.gd","project/text_tail_arrange_test.gd","project/name_tail_layout_test.gd","project/guild_mark_tail_test.gd","project/test_whisper_chat_parity.gd","project/chat_mobile_ui_test.gd","project/test_chat_hyperlink_dice_parity.gd","build/extension/net_entity_test","build/extension/net_classic_session_test"],"reason":"聊天输入/公共路由、尾标单槽与生命周期、名字/称号/等级/公会名排布、移动聊天、私聊 helper 和基础 GC_CHAT/GC_WHISPER packet 测试通过;但 test_whisper_chat_parity 只覆盖未接入 live ChatUI 的 helpernative 测试未覆盖 whisper mode/无 VID notice/未知 VID/过滤/发送失败回显/重连清理,因此合同不能标记 PASS。"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"social.party_guild_messenger","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameActor.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonGuild.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonMessenger.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonCharacterManager.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/GuildMarkDownloader.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/GuildMarkUploader.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/MarkManager.cpp","../40250/Server Client TMP4/Server Client TMP4/ClientVS22/source/UserInterface/Packet.h","../40250/Server Client TMP4/Client/Eternexus/root/uiparty.py","../40250/Server Client TMP4/Client/Eternexus/root/uiguild.py","../40250/Server Client TMP4/Client/Eternexus/root/uimessenger.py","../40250/Server Client TMP4/Client/Eternexus/root/uiuploadmark.py","../40250/Server Client TMP4/Client/Eternexus/root/game.py","../40250/Server Client TMP4/Client/Eternexus/root/interfacemodule.py","../40250/Server Client TMP4/Client/Eternexus/root/uitaskbar.py","project/party_management_system.gd","project/guild_skill_system.gd","project/guild_war_system.gd","project/guild_war_observer_arena_system.gd","project/messenger_system.gd","project/guild_mark_uploader_system.gd","project/ui/party_ui.gd","project/ui/guild_ui.gd","project/ui/friend_ui.gd","project/game_scene.gd","project/net_world.gd","project/app_flow.gd","extension/src/net/m2_client.cpp","extension/src/net/m2_client.h","extension/src/net/entity_store.cpp","extension/src/net/entity_store.h","extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_session.h","extension/src/net/classic/classic_parser.cpp","extension/src/net/classic/classic_mark_client.cpp","extension/src/net/classic/classic_mark_client.h","extension/src/net/classic/wire_classic.h","audit/contracts/social.party-guild-messenger.md"],"reason":"已完成组队、公会、好友/Messenger、会徽/战旗和相关 UI/native 回包链审计。确认 native live 主路径较完整,但 party/guild skill/war/messenger/mark 本地 helper 仍直接改状态或计算权威结果;会徽下载虽然有独立 mark client,真实 index/CRC/block/断线恢复测试缺失;权限拒绝、重复/乱序、离会/重连清理证据不足。合同保持 PARTIAL,未修改实现。"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"social.party_guild_messenger","result":"PARTIAL","tests":["project/test_party_management_parity.gd","project/test_messenger_parity.gd","project/test_guild_mark_uploader_parity.gd","project/guild_mark_test.gd","project/guild_mark_tail_test.gd","project/test_guild_war_parity.gd","project/test_guild_war_observer_arena_parity.gd","project/test_guild_skill_parity.gd","project/guild_creation_ui_test.gd","project/test_privilege_empire_guild_parity.gd","project/p8_test.gd","build/extension/net_entity_test","build/extension/net_classic_session_test"],"reason":"组队 helper 30/30、Messenger helper 27/27、会徽上传 12/12、公会战 25/25、观察者 21/21、公会技能 31/31 和相关 UI/native 基础测试通过;但多项测试主要验证本地状态机或 fake client,未覆盖 GC_PARTY/GC_MESSENGER/GC_GUILD 权限拒绝、重复/乱序/重连和 mark client index/CRC/压缩 block/损坏恢复,因此合同不能标记 PASS。"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"social.exchange_safebox","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonExchange.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonSafeBox.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp","../40250/Server Client TMP4/Client/Eternexus/root/uiexchange.py","../40250/Server Client TMP4/Client/Eternexus/root/uisafebox.py","../40250/Server Client TMP4/Client/Eternexus/root/game.py","project/player_trade_exchange_system.gd","project/safebox_storage_keeper_system.gd","project/ui/exchange_ui.gd","project/ui/safebox_ui.gd","project/ui/mall_ui.gd","extension/src/net/m2_client.cpp","extension/src/net/m2_client.h","extension/src/net/entity_store.cpp","extension/src/net/entity_store.h","extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_session.h","audit/contracts/social.exchange-safebox.md"],"reason":"已完成玩家交易、交易确认/防调包、仓库/安全箱、密码、商城和金币确认的逐分支/协议/状态审计。确认 native exchange 请求缺 40250 __CanActMainInstance 等动作门控;ExchangeUI 的 _offered_cells 没有按 GC_ITEM_ADD/ITEM_DEL 重建,取消/距离超限会在等待 GC_END 前立即本地关闭;Safebox 移动端 pending/首空位和窗口 close 也有 optimistic 状态;player_trade_exchange_system.gd 与 safebox_storage_keeper_system.gd 直接计算交易结算、库存、密码、冷却和金条规则,属于本地 authority 旁路而非 40250 客户端实现。合同保持 PARTIAL,未修改实现。"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"social.exchange_safebox","result":"PARTIAL","tests":["project/test_player_trade_exchange_parity.gd","project/test_safebox_mall_parity.gd","project/test_safebox_storage_keeper_parity.gd","project/shop_cube_mall_test.gd","project/test_mall_affect_parity.gd","project/complex_item_drop_test.gd","project/popup_windows_parity_test.gd","project/test_security_lock_parity.gd","build/extension/net_entity_test","build/extension/net_classic_session_test"],"reason":"交易 helper 28/28、Safebox/Mall fake-client 测试 37/37、storage helper 37/37、mall 辅助 26/26、安全锁 48/48、基础 native parser/session 测试通过;complex_item_drop_test 仍有 1 项失败(购买模式允许拖放到出售目标)。现有通过项主要验证 helper/fake client/基础 parser,未覆盖真实 exchange/safebox/mall 服务器拒绝、GC 回包乱序、断线、回滚和 UI optimistic 状态清理,因此合同不能标记 PASS。"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"quest.quest_event_navigation","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonQuest.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonEventManager.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonEventManager.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamEvent.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonMiniMap.cpp","../40250/Server Client TMP4/Client/Eternexus/root/uiquest.py","../40250/Server Client TMP4/Client/Eternexus/root/interfacemodule.py","../40250/Server Client TMP4/Client/Eternexus/root/uicharacter.py","../40250/Server Client TMP4/Client/Eternexus/root/uiminimap.py","../40250/Server Client TMP4/Client/Eternexus/root/atlasinfo.txt","project/ui/quest_log.gd","project/ui/quest_dialog.gd","project/ui/quest_curtain.gd","project/ui/char_status_ui.gd","project/ui/atlas_ui.gd","project/ui/minimap.gd","project/atlas_navigation_system.gd","project/game_scene.gd","extension/src/net/m2_client.cpp","extension/src/net/m2_client.h","extension/src/net/entity_store.cpp","extension/src/net/entity_store.h","extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_session.h","project/biologist_quest_system.gd","project/dynamic_bounty_event_system.gd","project/event_manager_system.gd","project/metin_spawn_event_system.gd","audit/contracts/quest.quest-event-navigation.md"],"reason":"已完成任务状态、任务计时/计数、任务信件按钮、GC_SCRIPT/CPythonEventManager 42 标签、确认/输入/选择、地图信号、Atlas/小地图和过场链审计。确认 EntityStore 对 GC_QUEST_INFO END 不删除旧任务,缺少 reference 的 start timestamp 且 unordered_map 导致任务顺序不稳定;QuestLog/CharStatusUI 的负数任务按钮索引被 M2Client::script_button 的 idx<0 门控拒绝;QuestDialog 的 DONE 点击多发 script_answer(254)ESC 结束态走 quest_cancelRUN_CINEMA 仅发 signal 且 GameScene 未连接消费者;ADDMAPSIGNAL 只写 MinimapAtlas 绘制不读取信号点;本地生物学家/悬赏/活动 helper 是自定义 authority。合同保持 PARTIAL,未修改实现。"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"quest.quest_event_navigation","result":"PARTIAL","tests":["project/quest_test.gd","project/quest_event_test.gd","project/test_quest_dialog_parity.gd","project/test_quest_hud_parity.gd","project/quest_curtain_test.gd","project/atlas_test.gd","project/test_atlas_navigation_parity.gd","project/test_map_name_shower_parity.gd","project/test_minimap_radar_parity.gd","project/test_biologist_quest_parity.gd","project/test_event_manager_parity.gd","build/extension/net_entity_test","build/extension/net_classic_session_test","build/extension/net_classic_wire_test"],"reason":"脚本/事件 parser、QuestDialog 45 项、Quest HUD 19/19、镜幕、Atlas、导航 23 项、地图横幅 10/10、小地图 6/6、生物学家 28/28、活动 helper 24/24 及 native quest/script/wire 基础测试通过;但现有测试使用 fake client 或本地 helper,且 test_quest_dialog_parity 明确把 DONE→script_answer(254) 当作通过,未覆盖 40250 DONE 只关闭、任务 END 删除、计时持续、负数 sentinel、RUN_CINEMA 消费和 Atlas 任务信号,因此合同不能标记 PASS。"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"world.dungeon_activity","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/GameLib/MapManager.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/GameEventManager.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/GameEventManager.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Packet.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonEventManager.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonEventManager.h","project/dungeon_state.gd","project/ui/dungeon_result_ui.gd","project/game_scene.gd","project/world_boss_system.gd","project/dungeon_ranking_system.gd","project/spider_dungeon_system.gd","project/spider_dungeon_key_system.gd","project/flame_dungeon_razador_system.gd","project/endless_spire_dungeon_system.gd","extension/src/net/entity_store.cpp","extension/src/net/entity_store.h","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_session.cpp","audit/contracts/world.dungeon-activity.md"],"reason":"已完成 GC_DUNGEON 目标点、TIME_ATTACK_START、目标到达/20 秒重复提示、DUNGEON_RESULT 九字段结果、地图事件效果以及 Boss/排行/具体副本 helper 的逐分支审计。确认目标坐标/Manhattan 10000cm/20秒状态算法接近 40250,但 alarm_requested 未接入等价 compass/mse 资源消费者;结果链缺少 live 回包、拒绝、重复/乱序、断线和重连证据;world_boss、dungeon_ranking 及具体副本脚本是本地 authority40250 Windows 客户端没有同等实现,不能判定 parity。合同保持 PARTIAL,未修改实现。"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"world.dungeon_activity","result":"PARTIAL","tests":["project/dungeon_state_test.gd","project/dungeon_result_test.gd","project/test_dungeon_ranking_parity.gd","project/test_spider_dungeon_parity.gd","project/test_spider_dungeon_key_parity.gd","project/test_flame_dungeon_razador_parity.gd","project/test_endless_spire_dungeon_parity.gd","build/extension/net_entity_test","build/extension/net_classic_session_test","build/extension/net_classic_wire_test"],"reason":"目标状态、结果窗口、本地排行/蜘蛛/烈焰/无限塔 helper 以及 native parser/session/wire 基础测试通过;但测试没有证明 compass/mse alarm 实际消费、DUNGEON_RESULT live UI 时序、目标/结果乱序和 server rejection、断线重连清理,也不能把当前端自定义 dungeon/Boss/ranking authority 视为 40250 客户端 parity。"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"world.fishing_mining","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInput.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBase.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseMotion.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Packet.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoorWater.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/AreaTerrain.cpp","project/fishing_mining_system.gd","project/fishing_rod_reel_system.gd","project/fishing_cooking_camp_system.gd","project/mining_refinery_smelt_system.gd","project/net_play.gd","project/net_world.gd","extension/src/metin2_world.cpp","extension/src/metin2_world.h","extension/src/water_builder.cpp","extension/src/water_motion.h","extension/src/net/entity_store.cpp","extension/src/net/entity_store.h","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_parser.cpp","extension/src/net/classic/wire_classic.h","audit/contracts/world.fishing-mining.md"],"reason":"已完成钓鱼输入/CanFishing/GetFishingRot 水面扫描、CG/GC_FISHING 六类分支、GC_DIG_MOTION、地图水属性/水高/水面构造以及当前端钓鱼/采矿/烹饪/营火/熔炼 helper 审计。确认协议 parser、600cm 左右 10度扫描、水面测试和角色动作入口存在,但真实持竿/持镐门控、REACT 的 IsFishing 条件、DIG count 多动作、资源/音效/库存回包和断线/乱序清理未完整等价;本地收益/库存/熔炼脚本是 custom/server-like authority40250 Windows 客户端不承担这些职责。合同保持 PARTIAL,未修改实现。"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"world.fishing_mining","result":"PARTIAL","tests":["project/test_fishing_mining_parity.gd","project/test_fishing_rod_reel_parity.gd","project/test_fishing_cooking_camp_parity.gd","project/test_mining_refinery_smelt_parity.gd","project/fishing_water_test.gd","project/water_reference_test.gd","project/netplay_test.gd","project/netbridge_test.gd","project/combat_fx_test.gd","project/chat_test.gd","build/extension/net_entity_test","build/extension/net_classic_session_test","build/extension/net_classic_wire_test"],"reason":"钓鱼/采矿 26/26、鱼竿 33/33、烹饪营火 23/23、熔炼 21/21、水属性、水面几何、NetPlay/NetWorld/Chat 和 native parser/session/wire 基础测试通过;但现有测试主要验证 helper/fake client/基础事件,未证明 live CanFishing/持镐门控、REACT IsFishing、DIG count 多动作、服务端拒绝、资源音效、库存回包、乱序、断线和重连,因此合同不能标记 PASS。"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"world.mount_pet_polymorph","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerSkill.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBase.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseMotion.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBase.h","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstance.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameActor.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Packet.h","project/horse_system.gd","project/horse_combat_system.gd","project/horse_level_growth_system.gd","project/pet_companion_system.gd","project/classic_pet_system.gd","project/polymorph_system.gd","project/polymorph_marble_system.gd","project/mounted_combat_skill_system.gd","project/net_play.gd","project/net_world.gd","project/ui/equip_model.gd","extension/src/net/entity_store.cpp","extension/src/net/entity_store.h","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_parser.cpp","extension/src/net/classic/wire_classic.h","audit/contracts/world.mount-pet-polymorph.md"],"reason":"已完成 mount_vnum/GC_MOUNT、角色 motion mode/旋转速度、骑乘攻击/技能门、变身 affect/装备遮挡以及宠物/马匹 helper 审计。确认 native parser/store、mount_changed、部分 motion/攻击门存在,但未发现 mount_vnum 到实际 horse actor/model attach/detach 的链;EquipModel._is_poly 恒 false,变身/宠物/马匹成长/耐力/马上技能脚本属于当前端 custom/server-like authority40250 ClientVS22 未提供同等客户端 authority。合同保持 PARTIAL,未修改实现。"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"world.mount_pet_polymorph","result":"PARTIAL","tests":["project/test_mount_horse_parity.gd","project/test_horse_combat_parity.gd","project/test_horse_level_growth_parity.gd","project/test_mounted_combat_skill_parity.gd","project/test_pet_companion_parity.gd","project/test_classic_pet_parity.gd","project/test_polymorph_parity.gd","project/test_polymorph_marble_parity.gd","project/netplay_test.gd","project/netbridge_test.gd","build/extension/net_entity_test","build/extension/net_classic_session_test"],"reason":"马匹 24/24、骑战 32/32、成长 42/42、马上技能 25/25、宠物 40/40/31/31、变身 25/25/32/32 及部分 NetPlay/native parser 测试通过;但这些主要验证本地 helper/字段门控,未覆盖 mount actor/model attach、GC_MOUNT 位置/动画、poly native affect/shape、宠物 live 协议、服务器拒绝、乱序、死亡/切图/断线清理,因此合同不能标记 PASS。"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"world.npc_drop_actor_spawn","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameActor.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/NetworkActorManager.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonCharacterManager.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBase.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonItem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonTextTail.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Packet.h","extension/src/net/classic/classic_parser.cpp","extension/src/net/classic/wire_classic.h","extension/src/net/entity_store.cpp","extension/src/net/entity_store.h","extension/src/net/m2_client.cpp","project/net_world.gd","project/ui/mob_view.gd","project/ui/ground_items.gd","project/entity_rules.gd","project/game_scene.gd","project/metin_spawn_event_system.gd","project/mob_drop_scatter.gd","audit/contracts/world.npc-drop-actor-spawn.md"],"reason":"已完成 NPC/怪物/建筑/掉落物/所有权/私人商店招牌的 actor、ground、text-tail、协议和场景层逐分支审计。确认 native parser/store、实体两层生命周期、NPC/怪物模型、ground add/owner/del 和 shop_sign 字段入口存在;但 net_world_vis_test 复现 4 项可见性/裁剪失败,远端节点创建与离开范围清理不等价;ground 使用通用 bag/BoxMesh fallback,完整 CItemData drop model/effect/sound、建筑碰撞、拾取 live 回包和商店 UI 时序仍缺证据;本地掉落散落/活动石头/owner 保护属于 custom authority。合同保持 PARTIAL,本轮未修改实现。"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"world.npc_drop_actor_spawn","result":"PARTIAL","tests":["project/net_world_vis_test.gd","project/entity_rules_test.gd","project/forest_mob_render_test.gd","project/mob_view_test.gd","project/net_world_push_test.gd","project/test_ground_pickup_parity.gd","project/mob_death_drop_test.gd","project/test_mob_drop_scatter_parity.gd","project/mob_winding_test.gd","project/test_metin_spawn_event_parity.gd","build/extension/net_entity_test","build/extension/net_classic_session_test","build/extension/net_classic_wire_test"],"reason":"实体规则、NPC/怪物模型、推开、ground pickup、死亡掉落、散落、绕序和 Metin 活动测试通过;forest_mob_render_test 为 24 results/0 failures/4 fallbacks 且有 ObjectDB leak warningnet_world_vis_test 明确失败 4 项:范围内远端节点未构建、节点单次构建、范围外裁剪和 entity_removed 单次发射。native entity/session/wire 基础测试通过,但未覆盖真实资源失败、完整拾取回包、商店牌匾、visibility 和重连组合清理,因此合同不能标记 PASS。"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"movement.motion_resource_events","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseMotion.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceMotion.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceMotionEvent.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/RaceMotionData.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/RaceData.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/RaceData.h","../40250/Server Client TMP4/ClientVS22/source/GameLib/RaceManager.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseBattle.cpp","project/ui/player_view.gd","project/ui/remote_player_view.gd","project/ui/mob_view.gd","project/ui/msa_motion.gd","formats/msa.cpp","formats/msa.h","formats/msm.cpp","formats/msm.h","extension/src/metin2_anim.cpp","extension/src/metin2_anim.h","project/net_play.gd","project/game_scene.gd","project/fx/motion_effect_anchor.gd","project/hit_collision.gd","audit/contracts/movement.motion-resource-events.md"],"reason":"已完成 RaceData motion key/权重/父模式、RaceMotionData 的 duration/accumulation/combo/attack/loop/event、ActorInstance motion queue/frame event 与当前 MSA/MSM/Metin2AnimPlayer/PC-NPC-remote view/NetPlay 对照。确认当前端有基础解析、GR2 播放、crossfade、root speed、combo/hit window 和本地主角事件入口;但 motion 权重使用等权随机,MSM 只解析 base/hairLoopData 只暴露未执行,AnimPlayer 播放 duration 取 GR2 而非以 MSA MotionDuration 为权威,非主角没有完整 MotionEventProcess 消费,动作队列/事件帧时序和失败回退不统一。合同保持 PARTIAL,本轮未修改实现。"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"movement.motion_resource_events","result":"PARTIAL","tests":["project/player_motion_test.gd","project/keyboard_motion_timeline_test.gd","project/race_motion_assembly_test.gd","project/animation_blend_test.gd","project/animation_cache_test.gd","project/test_combo_continuous_flow.gd","project/combat_fx_test.gd","project/eterngrn_polish_test.gd","project/target_effect_test.gd","project/hit_collision_test.gd","project/motion_effect_anchor_test.gd","project/mob_view_test.gd"],"reason":"基础动作、键盘时间线、8 race 资源装配、crossfade、连击、命中窗、防御球、挂点、目标特效和 NPC 模型测试通过;animation_cache_test 失败 2 项(hot motion switches 未达到 decoded clip/MSA metadata 复用预期,统计 hits=3/misses=3、msa_hits=3/msa_misses=3);eterngrn_polish_test 有未入树 Node3D transform、ObjectDB/RID leak warning。现有测试主要覆盖当前端 helper/资源样本,未覆盖完整 RaceData weighted motion、LoopData、所有 actor 的 MotionEventProcess、动作队列和断线/换图清理,因此合同不能标记 PASS。"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"combat.target_selection_rules","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBase.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseBattle.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInput.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","project/entity_rules.gd","project/net_play.gd","project/player_controller.gd","project/target_board.gd","project/net_world.gd","audit/contracts/combat.target-selection-rules.md"],"reason":"已逐分支核对 IsAttackableInstance、SetTarget/CanChangeTarget/IsTargetableInstance、CanPickInstance、RecvTargetPacket/CanViewTargetHP、NotifyCharacterDead/Update 和安全区判定。当前 entity_rules 的攻击资格分支基本镜像,但 _change_target_to_picked_instance 没有统一执行 CanChangeTarget/CanPickInstance,射线只排除 dead,实体更新缺少统一目标失效回调,in_safe 尚未证明由地图 ATTRIBUTE_BANPK 实时驱动;合同保持 PARTIAL,未修改实现。"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"combat.target_selection_rules","result":"PARTIAL","tests":["project/entity_rules_test.gd","project/target_board_test.gd","project/test_alignment_pk_parity.gd","project/test_click_target_effect_parity.gd","project/test_auto_combat_bot_parity.gd","project/playable_combat_test.gd"],"reason":"攻击资格矩阵、目标框分派/HP 可见性、善恶 PK、点击目标光圈/飞行物和自动战斗测试通过;但没有覆盖 CanChangeTarget 锁门、CanPickInstance 的隐身/视锥/门死亡分支、目标死亡/裁剪/迟到更新清理、ATTRIBUTE_BANPK 与 in_safe 同步、SetTarget 时序和真实服务端目标包,因此合同不能标记 PASS。"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"combat.flying_projectile","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/GameLib/FlyingData.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/FlyingInstance.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/FlyTarget.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/FlyingObjectManager.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerEventHandler.cpp","project/fly_object.gd","project/net_world.gd","project/net_play.gd","project/world_shot.gd","audit/contracts/combat.flying-projectile.md"],"reason":"已逐分支核对 .fly 数据、弓箭 FLY/SHOOT、GC_FLY_TARGETING/ADD/CREATE、CFlyingInstance homing/线段命中/超程/背景碰撞/穿透/回收和地图清理。当前端基础单目标/坐标目标/经验球/静态背景碰撞和 reset 链存在,但普通飞行物使用脚本合成参数,没有完整 .fly loaderhit-on-another-monster 动态 Actor 碰撞、命中集合和另一目标回调缺失,索引飞行类型/特效资源也未逐类等价。合同保持 PARTIAL,未修改实现。"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"combat.flying_projectile","result":"PARTIAL","tests":["project/fly_test.gd","project/fly_reset_test.gd","project/test_exp_fly_parity.gd","project/fly_target_bounds_test.gd","project/test_click_target_effect_parity.gd","project/combat_fx_test.gd"],"reason":"飞行物基础弹道、目标命中/超程、地图清理、经验光球、目标包围球中心、静态障碍碰撞和 combat FX 测试通过;fly_test/fly_reset_test/test_exp_fly_parity/fly_target_bounds_test/test_click_target_effect_parity 有 ObjectDB/RID/resource cleanup 警告。没有动态 Actor 碰撞、.fly 资源矩阵、pierce 多目标、目标删除/VID 重用、目标包乱序、sequence 和真实服务端弓箭闭环证据,因此合同不能标记 PASS。"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"combat.affect_status","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/AffectFlagContainer.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBase.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseEffect.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseBattle.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/NetworkActorManager.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameActor.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Packet.h","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceBattle.cpp","extension/src/net/classic/classic_parser.cpp","extension/src/net/entity_store.cpp","extension/src/net/entity_store.h","extension/src/net/m2_client.cpp","project/combat_status_effect_system.gd","project/ui/hit_reaction.gd","project/ui/player_view.gd","project/ui/mob_view.gd","project/net_play.gd","project/net_world.gd","project/game_scene.gd","project/hud.gd","audit/contracts/combat.affect-status.md"],"reason":"已逐分支核对 AffectFlagContainer、SetAffectFlagContainer/清理、GC_DAMAGE_INFO、GC_STUN、GC_AFFECT_ADD/REMOVE、HitGood/Great/Stone、网络状态拒收和当前 native/GDScript 链。确认 affect bitset、damage/affect parser、基础状态图标信号和受击 helper 存在,但 combat_status_effect_system.gd 在客户端本地 roll 状态、tick 并直接改 HP,数据权威与 40250 Windows 客户端不一致;远端 stunned/knockdown、stone smoke/building no-op、完整 effect/icon 资源和清理时序也未完全等价。合同保持 PARTIAL,本轮未修改实现。"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"combat.affect_status","result":"PARTIAL","tests":["project/test_combat_status_effect_parity.gd","project/damage_effect_test.gd","project/combat_fx_test.gd","project/test_mob_combat_reaction_parity.gd","project/test_combat_death_pickup_entry_parity.gd","project/hit_view_test.gd","build/extension/net_entity_test","build/extension/net_classic_session_test"],"reason":"本地状态模拟器 24/24、damage effect、combat FX、mob reaction、死亡/动作锁和 native entity/session 测试通过;hit_view_test 失败 1 项:前向受击期望 damage/damage_1.msa,实际仍为 onehand_sword/combo_01.msa。通过项主要证明当前 helper/parser 行为,不能证明服务端状态权威、逐 affect 资源、远端 stunned/knockdown、乱序/过期/换图清理已等价。"}
{"time":"2026-09-20T00:00:00Z","event":"audit_finding","id":"skill.player_ui_cooldown","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonSkill.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerSkill.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBase.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Packet.h","project/player_skill.gd","project/ui/skill_table.gd","project/ui/skill_ui.gd","project/ui/quickbar.gd","project/net_play.gd","extension/src/net/entity_store.cpp","extension/src/net/entity_store.h","extension/src/net/classic/classic_parser.cpp","extension/src/net/m2_client.cpp","audit/contracts/skill.player-ui-cooldown.md"],"reason":"已逐分支核对 RegisterSkillTable/skill formula、ClickSkillSlot、CanUseSkill、CheckSkillUsable、UseSkill、目标/射程预约、RunCoolTime、skill level/group/quickslot/cooldown-end 包和当前 SkillTable/PlayerSkill/Quickbar/native 链。确认技能属性、主要三层校验、36 槽 quickslot 和 cooldown-end 入口存在,但当前 CanUseSkill 缺少 poly/dress/pickaxe/horse/graphic motion 五类门控;Quickbar/points 缺少 POINT_CASTING_SPEED 冷却修正;full skill flow 测试引用缺失 fixture。合同保持 PARTIAL,本轮未修改实现。"}
{"time":"2026-09-20T00:00:00Z","event":"test_run","id":"skill.player_ui_cooldown","result":"PARTIAL","tests":["project/player_skill_test.gd","project/skill_test.gd","project/test_skill_inventory_parity.gd","project/test_taskbar_quickslot_parity.gd","project/test_status_skill_reset_parity.gd","project/mobile_gesture_test.gd","project/playable_combat_test.gd","project/test_full_skill_flow.gd","build/extension/net_entity_test","build/extension/net_classic_session_test"],"reason":"player_skill、skill table/UI、技能库存/门控、quickslot、技能重置、移动手势、可玩技能请求和 native entity/session 测试通过;test_taskbar_quickslot_parity 有 ObjectDB/RID/resource cleanup 警告;test_full_skill_flow.gd 无法启动,解析失败:res://net_client_fake.gd 不存在。现有通过项未覆盖 casting speed、CanUseSkill 五类缺失门、full flow fixture、乱序/断线/重连和服务端拒绝。"}
{"time":"2026-09-20T15:57:27Z","event":"audit_finding","id":"render.effect_particle_motion","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/GameLib/RaceMotionData.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/RaceMotionDataEvent.h","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceMotionEvent.cpp","../40250/Server Client TMP4/ClientVS22/source/EffectLib/EffectManager.cpp","../40250/Server Client TMP4/ClientVS22/source/EffectLib/EffectInstance.cpp","../40250/Server Client TMP4/ClientVS22/source/EffectLib/ParticleInstance.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonEffectModule.cpp","formats/msa.cpp","formats/msa.h","extension/src/metin2_anim.cpp","project/fx/effect_player.gd","project/fx/mde.gd","project/fx/mse.gd","project/fx/skill_fx.gd","project/fx/effect_registry.gd","project/fx/motion_effect_anchor.gd","project/fx/target_effect_anchor.gd","project/game_scene.gd","project/ui/player_view.gd","project/ui/remote_player_view.gd","project/ui/mob_view.gd","project/net_world.gd","audit/contracts/render.effect-particle-motion.md"],"reason":"已完成 MDE/MSE/粒子曲线/混合/生命周期、MSA MotionEventData、EFFECT/EFFECT_TO_TARGET/FLY/SPECIAL_ATTACKING/SOUND/SCREEN_WAVING/CHARACTER_SHOW/HIDE/WARP 和本地/远端 Actor 消费链审计。确认基础 MDE/MSE、EffectPlayer、registry、骨骼/目标 anchor 和本地主角事件信号存在,但 MotionEvent 未保留 FLY/SPECIAL_ATTACKING/屏幕震动/显示隐藏/warp 专用字段,type 4/6/7/8/9 分支缺失或不完整,远端 PC/NPC/Mob 未连接动作事件。当前资产统计 type 1=1892、2=263、4=818、6=268、7=47、8=47、9=47、10=197,共 3579 个事件,因此合同从 MAPPED 降为 PARTIAL;本轮未修改实现。"}
{"time":"2026-09-20T15:57:27Z","event":"test_run","id":"render.effect_particle_motion","result":"PARTIAL","tests":["project/fx_test.gd","project/effect_playback_test.gd","project/motion_effect_anchor_test.gd","project/target_effect_test.gd","project/skill_fx_test.gd","project/effect_color_test.gd","project/effect_emission_test.gd","project/effect_faces_test.gd","project/effect_lie_test.gd","project/effect_random_rotation_test.gd","project/effect_render_regression_test.gd","project/effect_rotation_test.gd","project/effect_scale_test.gd","project/effect_space_test.gd","project/effect_surface_test.gd","project/effect_texture_animation_test.gd"],"reason":"MSE/MDE、EffectPlayer、目标特效、技能 FX、颜色/发射/面向/lie/随机旋转/渲染回归/旋转/缩放/空间测试均无断言失败;surface 和 texture animation 在 headless 明确跳过像素检查。motion_effect_anchor_test 虽打印 failures=0,但进程 exit 139 且有 6 个 ObjectDB 泄漏,不能作为稳定通过证据;其它测试未覆盖所有 Actor 的 MotionEventProcess、type 4/6/7/8/9、真实 .fly、splash、远端特效和跨图清理。"}
{"time":"2026-09-20T16:00:00Z","event":"audit_finding","id":"render.model_attachment","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/ThingInstance.cpp","../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/ThingInstance.h","../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/LODController.cpp","../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/LODController.h","../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/ModelInstanceUpdate.cpp","../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/ModelInstance.cpp","../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/ModelInstanceMotion.cpp","../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/ModelInstanceModel.cpp","../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/ModelInstanceRender.cpp","../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/ModelInstanceCollisionDetection.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceAttach.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/RaceData.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/RaceData.h","../40250/Server Client TMP4/ClientVS22/source/GameLib/ItemData.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBase.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseRender.cpp","extension/src/metin2_model.h","extension/src/metin2_model.cpp","extension/src/metin2_anim.cpp","extension/src/gr2_bridge.cpp","project/ui/player_view.gd","project/ui/equip_model.gd","project/ui/remote_player_view.gd","project/ui/mob_view.gd","project/ui/race_spec.gd","audit/contracts/render.model-attachment.md"],"reason":"已完成 ThingInstance/LODController/ModelInstance/ActorInstanceAttach/RaceData/ItemData 与当前 GR2/Godot 模型链的首轮逐分支审计。确认当前默认 LOD 为 18/42/90m,而 40250 Actor 分档使用 500/1500/2500cm;当前 LOD 仅替换单骨骼下的网格并使用自定义 LodGhost,未证明动作、子模型挂点、碰撞和 bounds 的控制器级同步;weapon_attach_test 的 03150 warrior/run 左手挂点偏移 0.75m,超过 0.12m 阈值。合同降为 PARTIAL,本轮未修改实现。"}
{"time":"2026-09-20T16:00:00Z","event":"test_run","id":"render.model_attachment","result":"PARTIAL","tests":["project/weapon_attach_test.gd","project/gpu_lod_attachment_test.gd","project/gpu_pose_bounds_test.gd","project/race_motion_assembly_test.gd","project/equip_model_test.gd","project/remote_player_test.gd","project/mob_view_test.gd","project/rendering_scenario_test.gd","project/fly_target_bounds_test.gd","project/mob_winding_test.gd","project/animation_cache_test.gd"],"reason":"基础 GR2/装备/远端/怪物/LOD/姿态/bounds 断言大多通过,但 weapon_attach_test 有 1 项真实 03150 双手武器失败并 exit 139animation_cache_test 有 2 项热切换缓存失败并 exit 139;多项真实模型测试出现 ObjectDB 泄漏。因此证据只能标记 PARTIAL,不能宣称与 40250 统一。"}
{"time":"2026-09-20T16:20:00Z","event":"audit_finding","id":"ui.hud_target_minimap_status","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonTextTail.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonMiniMap.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonApplication.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerEventHandler.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBase.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseEffect.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/uitaskbar.py","../40250/Server Client TMP4/ClientVS22/source/UserInterface/uicharacter.py","../40250/Server Client TMP4/ClientVS22/source/UserInterface/uitarget.py","project/hud.gd","project/net_play.gd","project/net_world.gd","project/ui/char_status_ui.gd","project/ui/target_ui.gd","project/target_board.gd","project/ui/minimap.gd","project/text_tail.gd","project/text_tail_arrange.gd","project/chat_tail.gd","project/ui/ground_items.gd","project/ui/quickbar.gd","audit/contracts/ui.hud-target-minimap-status.md"],"reason":"已完成 PythonTextTail/PythonMiniMap/PythonPlayer/TargetBoard/TaskBar 与当前 GameScene/UI 链首轮逐分支审计。确认 target_board/target_ui 代码和 helper 测试存在,但正式 GameScene 未创建或注入 NetPlay.target_ui,生产目标框实际退回 hud.gd 简化面板;GameScene 同时创建 hud.gd 旧 minimap 与 ui/minimap.gd 新雷达,产生重复小地图;新 minimap 默认 scale 0.25、范围 0.101.25、按钮步进与 40250 默认 2.0、范围 0.54.0、×2/×0.5 不一致。TextTail 的 CanPickInstance/逐帧时序仍为近似。因此合同保持 PARTIAL,本轮未修改实现。"}
{"time":"2026-09-20T16:20:00Z","event":"test_run","id":"ui.hud_target_minimap_status","result":"PARTIAL","tests":["project/test_target_board_parity.gd","project/target_board_test.gd","project/test_minimap_radar_parity.gd","project/p9_test.gd","project/text_tail_test.gd","project/text_tail_arrange_test.gd","project/chat_tail_test.gd","project/chat_test.gd","project/name_show_test.gd","project/char_status_ui_test.gd","project/test_taskbar_quickslot_parity.gd","project/taskbar_dock_test.gd"],"reason":"目标分派/面板 helper 13 项、目标分类、坐标/按钮、尾标/聊天、角色状态、TaskBar/Quickslot 断言均通过;但 target_board_parity 通过的是手工注入 target_ui,未覆盖正式 GameScene 漏接;minimap 测试未检测重复创建和 40250 scale 常量;Quickbar 测试退出报告 221 个 ObjectDB、91 个 CanvasItem RID 和 3 个资源仍在使用,故不能标记等价或清理通过。"}
{"time":"2026-09-20T16:40:00Z","event":"audit_finding","id":"ui.input_camera_mobile","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonApplicationCamera.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonApplicationCursor.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInputMouse.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInputKeyboard.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonIME.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/Input.cpp","project/game_camera.gd","project/player_controller.gd","project/ui/mouse_controller.gd","project/ui/cursor_manager.gd","project/ui/mobile/mobile_window_host.gd","project/ui/mobile/mobile_input_overlay.gd","audit/contracts/ui.input-camera-mobile.md"],"reason":"已完成相机普通/站立/混合状态、连续旋转/俯仰/缩放、键盘 WASD 状态、鼠标智能点击、光标、IME 和移动端适配的首轮逐分支审计。确认移动端手势/窗口、鼠标拖放和键盘映射基础测试通过,但当前相机使用固定距离缩放且默认值/恢复快照与 40250 不一致;未完整复刻 NEW_SetMouseState 全按钮/连续光标/硬件光标显隐;IME 依赖 Godot LineEdit,没有 PythonIME 等价回调链,因此合同从 MAPPED 降为 PARTIAL。","tests":["project/game_camera_test.gd","project/mouse_controller_test.gd","project/input_key_test.gd","project/mobile_gesture_test.gd","project/mobile_ui_test.gd","project/mobile_window_host_test.gd"]}
{"time":"2026-09-20T16:40:00Z","event":"test_run","id":"ui.input_camera_mobile","result":"PARTIAL","tests":["project/game_camera_test.gd","project/mouse_controller_test.gd","project/input_key_test.gd","project/mobile_gesture_test.gd","project/mobile_ui_test.gd","project/mobile_window_host_test.gd"],"reason":"mouse_controller、input_key、mobile_gesture、mobile_ui、mobile_window_host 均无断言失败;game_camera_test 失败 3 项:默认距离 1550cm、默认俯仰角 27 度和 RESTORE_CAMERA 恢复保存普通视图,另有输入测试 ObjectDB/Camera RID 泄漏警告。通过项只证明局部适配,不足以宣称与 40250 相同。"}
{"time":"2026-09-20T17:00:00Z","event":"audit_finding","id":"audio.bgm_ambience_3d","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/MilesLib/SoundManager.cpp","../40250/Server Client TMP4/ClientVS22/source/MilesLib/SoundManager2D.cpp","../40250/Server Client TMP4/ClientVS22/source/MilesLib/SoundManager3D.cpp","../40250/Server Client TMP4/ClientVS22/source/MilesLib/SoundManagerStream.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonSoundManagerModule.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/Area.cpp","project/audio.gd","project/bgm_director.gd","project/app_lifecycle.gd","formats/area_data.cpp","extension/src/metin2_world.cpp","audit/contracts/audio.bgm-ambience-3d.md"],"reason":"已完成 2D/3D/Stream 声音入口、BGM 淡入淡出、音量曲线、listener 缩放、角色动作音效限频、Area LOOP/ONCE/STEP 和前后台恢复的首轮逐分支审计。确认当前 `.mss`/环境声/角色音效和基础 BGM 选曲存在,但当前采用 Godot 动态播放器/Tween,不是 Miles 固定实例池和逐帧音乐状态机;后台只静音 BGM,没有按 40250 SaveVolume 同时静音 SFX;加载失败状态回滚、快速换图清理和真实 3D attenuation 仍未证明,因此合同从 MAPPED 降为 PARTIAL。","tests":["project/audio_miles_test.gd","project/ambience_test.gd","project/bgm_test.gd","project/test_bgm_jukebox_parity.gd","project/app_flow_lifecycle_test.gd","project/system_option_ui_test.gd"]}
{"time":"2026-09-20T17:00:00Z","event":"test_run","id":"audio.bgm_ambience_3d","result":"PARTIAL","tests":["project/audio_miles_test.gd","project/ambience_test.gd","project/bgm_test.gd","project/test_bgm_jukebox_parity.gd","project/app_flow_lifecycle_test.gd","project/system_option_ui_test.gd"],"reason":"六组音频/环境声/BGM/生命周期/设置测试均无断言失败;但 bgm_test 的 FakeAudio 未验证后台 SFX 静音,点唱机测试不驱动真实 Audio,未覆盖 Miles 固定实例池、多实例音乐状态、加载失败回滚、快速换图和真实 3D 衰减,故只能记录 PARTIAL。"}
{"time":"2026-09-20T17:20:00Z","event":"audit_finding","id":"lifecycle.platform_release","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/EterLib/MSApplication.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/MSWindow.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonApplication.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonApplicationProcedure.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/CheckLatestFiles.cpp","../40250/Server Client TMP4/ClientVS22/source/EterPack/EterPackManager.cpp","project/client_main.gd","project/app_flow.gd","project/app_lifecycle.gd","project/asset_root.gd","project/asset_pack.gd","project/export_presets.cfg","build-macos-client.sh","build-android.sh","export-android.sh","audit/contracts/lifecycle.platform-release.md"],"reason":"已完成 Win32 应用/窗口消息循环、窗口尺寸与激活、全屏/关闭、初始化/异常、CheckLatestFiles CRC、EterPack 资源链和当前 Godot AppFlow/AssetPack/导出脚本的首轮逐分支审计。确认 AppFlow、AssetPack、macOS/Android 导出和局部生命周期测试存在,但当前没有 Windows 导出预设/构建链、MSWindow 等价层、CheckLatestFiles 更新检查或 Eter 异常处理;资源自包含依赖平台脚本和外部 zip,因此合同从 MAPPED 降为 PARTIAL。","tests":["project/app_flow_lifecycle_test.gd","project/dds_lifecycle_test.gd","godot --headless --path project --editor --quit","godot --headless --path project --export-release macOS /tmp/mtgodot-platform-audit.app"]}
{"time":"2026-09-20T17:20:00Z","event":"test_run","id":"lifecycle.platform_release","result":"PARTIAL","tests":["project/app_flow_lifecycle_test.gd","project/dds_lifecycle_test.gd","project --editor validation","macOS release export probe"],"reason":"AppFlow 生命周期测试、DDS 资源生命周期测试、Godot 编辑器项目校验和 macOS release export probe 均退出码通过;项目校验期间自动生成缺失 uid 缓存,导出通过不代表 Windows 导出/窗口/CRC/crash 路径存在。"}
{"time":"2026-09-20T17:40:00Z","event":"audit_finding","id":"world.environment_weather","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoorRender.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoorRenderHTP.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoorRenderSTP.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/SnowEnvironment.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/SnowParticle.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/EnvironmentMap.cpp","extension/src/environment_builder.cpp","extension/src/metin2_world.cpp","formats/environment.cpp","project/game_scene.gd","project/weather_daynight_system.gd","project/fx/weather.gd","audit/contracts/world.environment-weather.md"],"reason":"已完成 .msenv 环境加载、背景/角色方向光、fog、天空六面/云、screen filter、lens flare、风、SnowEnvironment/SnowParticle、昼夜 helper 与正式 GameScene 接入的首轮逐分支审计。确认 environment_test、skybox_test、p9_test 和 test_weather_daynight_parity 通过,但 filter/lens flare/wind 只有 metadata 或无运行时实现,fog 使用与 40250 不同的 Godot depth fogSnowEnvironment 池未复刻,WeatherDayNightSystem 未接入正式地图/天气链;合同从 MAPPED 降为 PARTIAL,本轮未修改实现。"}
{"time":"2026-09-20T17:40:00Z","event":"test_run","id":"world.environment_weather","result":"PARTIAL","tests":["project/environment_test.gd","project/skybox_test.gd","project/p9_test.gd","project/test_weather_daynight_parity.gd"],"reason":"四组环境、天空、通用天气粒子和昼夜 helper 测试均无断言失败;但测试没有覆盖 filter/lens flare/wind、线性 fog 参数、SnowEnvironment 池、正式 GameScene 天气接入、真实渲染顺序及快速切图/资源失败清理,因此不能标记为 40250 等价。"}
{"time":"2026-09-20T18:00:00Z","event":"audit_finding","id":"combat.death.exp_drop","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseBattle.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","project/net_world.gd","project/net_play.gd","project/player_controller.gd","audit/contracts/combat.death-exp-drop.md"],"reason":"下一轮沿正式 GC_DEAD/POINT_EXP/CREATE_FLY 调用链复核:POINT_EXP.amount 一次性累计、跨等级经验反馈和 CREATE_FLY 仅视觉已确认;但主角由 _local_node 单独持有,entity_dead 未统一接入 PlayerController.stop、自动攻击/预约清理、GameOver/复活门,POINT_* 的 ShowPointEffect/金币 amount/属性技能刷新也未完全等价。现有死亡/掉落/战斗测试均通过但没有覆盖这些缺口,合同继续 PARTIAL。"}
{"time":"2026-09-20T18:00:00Z","event":"test_run","id":"combat.death.exp_drop","result":"PASS","tests":["project/test_combat_death_pickup_entry_parity.gd","project/mob_death_drop_test.gd","project/combat_parity_test.gd","project/playable_combat_test.gd","project/gamescene_test.gd","build/extension/net_state_queue_test"],"reason":"六组现有回归测试退出码均通过;结果只证明局部死亡、掉落、经验增量队列、战斗锁和地图装配可运行,不证明与 40250 主角死亡状态门、完整 POINT_* 副作用、真实攻击包序和乱序/复活/跨图清理一致。"}
{"time":"2026-09-20T18:20:00Z","event":"audit_finding","id":"network.packet_dispatch_protocol","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStream.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Packet.h","extension/src/net/classic/classic_stream.cpp","extension/src/net/classic/wire_classic.h",".agents/skills/metin2-40250-parity-audit/scripts/audit_packet_registry.py","audit/contracts/network.packet-dispatch.md"],"reason":"新增机器化注册表复核:参考 CMainPacketHeaderMap 实际为 119 项(106 静态、13 动态),当前 packet_size_gc 有 108 个 case、is_dynamic_gc 有 15 个 case;当前额外将 WHISPER 和 SYMBOL_DATA 作为动态兼容分支。确认旧合同的 117 项计数错误并已纠正;WHISPER 分帧、四阶段 allowlist、burst tick、错误清理和动态长度重算差异仍保持 PARTIAL。"}
{"time":"2026-09-20T18:20:00Z","event":"test_run","id":"network.packet_dispatch_protocol","result":"PARTIAL","tests":[".agents/skills/metin2-40250-parity-audit/scripts/audit_packet_registry.py","build/extension/net_classic_stream_test","build/extension/net_classic_wire_test"],"reason":"注册表脚本和现有 framing/wire 测试均执行完成;脚本准确报告参考 119/106/13 与当前 108/15,额外动态适配为 WHISPER/SYMBOL_DATA。现有 C++ 测试通过,但未覆盖完整别名尺寸映射、阶段 allowlist、WHISPER 两段式边界及 40250 单 tick 语义。"}
{"time":"2026-09-20T18:25:00Z","event":"test_correction","id":"network.packet_dispatch_protocol","result":"PARTIAL","tests":[".agents/skills/metin2-40250-parity-audit/scripts/audit_packet_registry.py"],"reason":"修正 18:20 的计数说明:脚本排除了源码中注释掉的 SLOW_TIMER/TARGET_CREATE 两行,运行时有效参考注册表为 117 项(104 静态、13 动态),不是 119 项;当前额外动态适配 WHISPER/SYMBOL_DATA 仍使该域保持 PARTIAL。"}
{"time":"2026-09-20T18:45:00Z","event":"audit_finding","id":"network.reconnect_warp","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseLoading.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStream.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/NetStream.cpp","extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_stream.cpp","extension/src/net/m2_client.cpp","project/game_scene.gd","project/app_flow.gd","project/ui/reconnect_ui.gd","audit/contracts/network.reconnect-warp.md"],"reason":"完成重连/换图域第二轮逐行核对:GC_WARP 专用路径保留同一 ClassicSession、selected slot、login key 和 DirectEnter,但 generic reconnect 仍通过 warp_to_game_server 销毁旧 session,再由 start_offline 清空 selected/direct-enter 后依赖 char_list 回放;当前 ClassicStream 未见等价 CNetworkStream::m_connectLimitTime deadlineReconnectUI 也没有 client 级 in-flight guard。清理分散在 world_reset/EntityStore/NetPlay/NetWorld/UI,顺序尚未与 40250 SetLoadingPhase/旧 stream Clear 1:1 对齐。p10_test 暴露 Loading→Game 未隐藏和无 SceneTree 时 char-select timer 空树问题,合同继续 PARTIAL。"}
{"time":"2026-09-20T18:45:00Z","event":"test_run","id":"network.reconnect_warp","result":"PARTIAL","tests":["build/extension/net_classic_session_test","godot --headless --path project --script app_flow_lifecycle_test.gd","godot --headless --path project --script gamescene_test.gd","godot --headless --path project --script p9_test.gd","godot --headless --path project --script p10_test.gd"],"reason":"net_classic_session_test、app_flow_lifecycle_test、gamescene_test、p9_test 通过;p10_test 失败 3 项:Loading 遮罩在 phase=game 后仍可见、char-select 在无 SceneTree 构造阶段调用 create_timer 导致空树错误,并连带开始/重连角色回放断言失败。通过项只覆盖局部生命周期/换图行为,不能证明 generic reconnect 状态保留、连接 deadline、重复重试 guard 或真实旧/新 socket 竞态。"}
{"time":"2026-09-20T19:10:00Z","event":"audit_finding","id":"network.error_timeout_server_state","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/AccountConnector.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/ServerStateChecker.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseLogin.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/NetStream.cpp","extension/src/net/auth_client.h","extension/src/net/net_stream.cpp","extension/src/net/classic/classic_stream.cpp","project/net/channel_status.gd","project/app_flow.gd","audit/contracts/network.error-timeout-server-state.md"],"reason":"完成认证/连接/频道状态第二轮逐分支审计:当前 NetStream 没有 m_connectLimitTime 等价 deadlineClassicStream 在 Connecting 阶段直接以 SO_ERROR=0 切换 Online,未复刻参考可写事件确认;AuthClient/ClassicSession 发送登录后仍持有密码;ChannelStatus 已支持 classic 206/210 和分片 body,但 AppFlow 额外逐频道 TCP fallback,重复点击没有 in-flight/cancel/generation 保护。合同保持 PARTIAL。"}
{"time":"2026-09-20T19:10:00Z","event":"test_run","id":"network.error_timeout_server_state","result":"PARTIAL","tests":["godot --headless --path project --script channel_status_test.gd","MT_PROTOCOL=classic godot --headless --path project --script channel_status_test.gd","extension/tests/net_loopback_test.cpp","project/app_flow_lifecycle_test.gd","project/p10_test.gd"],"reason":"默认协议和 MT_PROTOCOL=classic 的 channel_status_test 均通过,认证 loopback 成功路径已有测试;但没有认证失败/远端关闭/连接挂起超时/密码清除断言,p10_test 仍有 Loading→Game 和无 SceneTree char-select 失败,因此解析成功不能提升为整体一致。"}
{"time":"2026-09-20T19:35:00Z","event":"audit_finding","id":"world.entity_spawn_state_sync","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/NetworkActorManager.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameActor.cpp","extension/src/net/classic/classic_parser.cpp","extension/src/net/entity_store.cpp","project/net_world.gd","project/net_world_vis_test.gd","audit/contracts/world.entity-spawn-state-sync.md"],"reason":"完成实体创建/附加信息/更新/删除/VID 重用/主 VID/可见性第二轮核对:参考 Actor manager 每次网络处理更新可见性,当前 NetWorld 100ms 节流导致 net_world_vis_test 4 项失败;当前同 VID Spawn 无条件保留旧位置,淡出期间新 Spawn 直接丢弃,非 PC Add/Add2 丢 state/affectgeneric AdditionalInfo 仍可 touch 未知实体,主 VID 清理范围也不完整。合同继续 PARTIAL。"}
{"time":"2026-09-20T19:35:00Z","event":"test_run","id":"world.entity_spawn_state_sync","result":"PARTIAL","tests":["build/extension/net_entity_test","godot --headless --path project --script net_world_vis_test.gd","project/gamescene_test.gd"],"reason":"net_entity_test 和 gamescene_test 通过;net_world_vis_test 失败 4 项:进入范围未建节点、far node 构建计数不符、离开范围未剔除、entity_removed 未发出一次。通过的 EntityStore/场景装配测试不能证明 Godot 可见性与 40250 Actor manager 时序一致。"}
{"time":"2026-09-20T20:00:00Z","event":"audit_finding","id":"world.map_load_transition","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/GameLib/MapManager.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoorLoad.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoorUpdate.cpp","extension/src/metin2_world.cpp","project/game_scene.gd","audit/contracts/world.map-load-transition.md"],"reason":"完成地图生命周期第二轮核对:40250 是 Leave→Property/Load→Environment→Enter,当前先 unload_map、同步建初始 stream_queue、再解析环境;当前半径外 chunk 立即 queue_free、无 map-name 校验、跨图 old/new world 短暂共存、无共享 generation/token,缺图会由 GameScene 降级平地继续。合同继续 PARTIAL。"}
{"time":"2026-09-20T20:00:00Z","event":"test_run","id":"world.map_load_transition","result":"PARTIAL","tests":["godot --headless --path project --script gamescene_test.gd","godot --headless --path project --script p9_test.gd","godot --headless --path project --script environment_test.gd","project/forest_map_render_test.gd"],"reason":"gamescene_test、p9_test、environment_test 通过;forest_map_render_test 不是可直接用 godot --headless --script 启动的 SceneTree 测试,本轮未计通过。通过项只覆盖场景装配、warp signal 和 msenv parser,不证明 Leave/Enter、map-name 校验、延迟回收、双 world 或中断加载一致。"}
{"time":"2026-09-20T20:25:00Z","event":"audit_finding","id":"movement.click_collision","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInputMouse.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseMovement.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceCollisionDetection.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoor.cpp","project/player_controller.gd","project/netplay.gd","extension/src/metin2_world.cpp","audit/contracts/movement.click-collision.md"],"reason":"完成点地/碰撞第二轮核对:参考端有 MBS_PRESS/MBS_CLICK 的按住状态机和未命中时 NEW_Stop,当前仅处理左键 pressed;参考使用 MSM 真实多碰撞球、Avoid/Adjust/BlockMovement,当前为固定半径+切线/xz 分轴近似;ray ground 的 1m/800m 采样也不同。四组回归通过但 click/target/fly 测试有 3 个 ObjectDB 泄漏和 1 个资源仍在使用警告,合同继续 PARTIAL。"}
{"time":"2026-09-20T20:25:00Z","event":"test_run","id":"movement.click_collision","result":"PARTIAL","tests":["godot --headless --path project --script player_move_test.gd","godot --headless --path project --script movement_parity_test.gd","godot --headless --path project --script netplay_test.gd","godot --headless --path project --script test_click_target_effect_parity.gd"],"reason":"四项断言测试均通过;最后一项仍在退出时报告 3 个 ObjectDB instances leaked 和 1 个 resources still in use。通过项覆盖 Src/Dst、gate、预约、切线和目标特效,不覆盖 press/hold/release、真实 MSM 球体、第二碰撞停止、桥/台阶 picking 或中断清理。"}
{"time":"2026-09-20T20:50:00Z","event":"audit_finding","id":"world.reset_cleanup","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseLoading.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStream.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonApplication.cpp","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","project/app_flow.gd","project/game_scene.gd","project/net_play.gd","project/net_world.gd","project/fly_object.gd","audit/contracts/world.reset-cleanup.md"],"reason":"完成换图、断线、退出和清理第二轮审计:40250 由 phase leave/Loading/Offline/Destroy 统一拥有清理顺序;当前 GC_WARP 才发 world_resetdisconnect_from_server 销毁 session 但不清保留的 GameScene;各清理器无统一 generationqueue_free 延迟且旧新 world 短暂共存。合同继续 PARTIAL。"}
{"time":"2026-09-20T20:50:00Z","event":"test_run","id":"world.reset_cleanup","result":"PARTIAL","tests":["build/extension/net_entity_test","godot --headless --path project --script fly_reset_test.gd","godot --headless --path project --script screen_hp_bar_test.gd","godot --headless --path project --script dungeon_state_test.gd","godot --headless --path project --script bgm_test.gd","godot --headless --path project --script rendering_scenario_test.gd"],"reason":"net_entity_test、dungeon_state_test、bgm_test 和 fly_reset_test 的断言退出码通过;fly_reset_test 退出时有 5 个 ObjectDB 泄漏。screen_hp_bar_test 退出码为 0 但打印 previously freed 访问错误;rendering_scenario_test failures=0 但退出码 139 且报告 54 个 ObjectDB 泄漏,均不能计为干净 PASS。"}
{"time":"2026-09-20T21:10:00Z","event":"audit_finding","id":"movement.remote_sync_state","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBase.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceSync.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/NetworkActorManager.cpp","extension/src/net/entity_store.cpp","extension/src/net/classic/classic_parser.cpp","project/net_world.gd","audit/contracts/movement.remote-sync-state.md"],"reason":"完成远端 TCP 状态队列第二轮复核:队首时间门、死亡/击倒门、70/30 EMA、根运动和动作前移动已有对应实现;但不可取消技能/表情/TCP 状态门、FUNC_EMOTION 距离分支、combo/skill arg 到具体动作资源以及 GC_SYNC_POSITION 的 TEMP_Push 碰撞/受击动作仍不等价,合同继续 PARTIAL。"}
{"time":"2026-09-20T21:10:00Z","event":"test_run","id":"movement.remote_sync_state","result":"PASS","tests":["build/extension/net_state_queue_test","build/extension/net_entity_test","godot --headless --path project --script net_world_vis_test.gd","godot --headless --path project --script netplay_test.gd","godot --headless --path project --script movement_parity_test.gd"],"reason":"五项回归均退出码 0;结果证明队列门、实体状态、可见性、上行移动和旋转/碰撞近似未回归,不覆盖真实模型动作资源、表情锁、不可取消技能、TEMP_Push 物理及实服乱序/跨图/死亡重建,因此合同整体仍为 PARTIAL。"}
{"time":"2026-09-20T21:30:00Z","event":"audit_finding","id":"skill.cast.effect_timing","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseBattle.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceMotionEvent.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerSkill.cpp","project/game_scene.gd","project/net_play.gd","project/net_world.gd","project/ui/player_view.gd","project/fx/skill_fx.gd","project/fx/effect_player.gd","audit/contracts/skill.cast-effect-timing.md"],"reason":"完成技能施法与效果时序第二轮核对:本地施法可按 grade 读取动作并按 MSA duration/cancel 门运行,通用 MSE 播放已有测试;但正式远端路径丢失循环次数、移动技能标志和 gradeSkillFx.spawn_skill 没有生产接线,MOTION_EVENT 的挂点/飞行/命中/声音时间线也未逐技能证明,合同继续 PARTIAL。"}
{"time":"2026-09-20T21:30:00Z","event":"test_run","id":"skill.cast.effect_timing","result":"PASS","tests":["godot --headless --path project --script skill_test.gd","godot --headless --path project --script combat_fx_test.gd","godot --headless --path project --script effect_playback_test.gd","build/extension/net_state_queue_test"],"reason":"四项回归均退出码 0;通过项覆盖技能表/UI、战斗门、通用特效播放/停止/重播和 FUNC_SKILL 队列,不覆盖逐技能 MSA→MSE→命中结果时间线、循环次数、移动技能、grade、挂点/颜色/混合及真实服务端结果。"}
{"time":"2026-09-20T21:50:00Z","event":"audit_finding","id":"network.login.phase_flow","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStream.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseHandShake.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseLogin.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseSelect.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseLoading.cpp","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_stream.cpp","project/app_flow.gd","project/ui/loading_screen.gd","project/ui/char_select_screen.gd","audit/contracts/network.login.phase-flow.md"],"reason":"完成登录/握手/认证/选人/Loading 第二轮核对:native/session 和 loopback 主链可用,但 PHASE_CLOSE→Login 语义、Loading UI owner、无 SceneTree char-select timer、失败重试清理、连接 deadline、可选安全分支和密码发送后清理仍不同,合同继续 PARTIAL。"}
{"time":"2026-09-20T21:50:00Z","event":"test_run","id":"network.login.phase_flow","result":"PARTIAL","tests":["build/extension/net_classic_session_test","build/extension/net_classic_stream_test","build/extension/net_loopback_test","godot --headless --path project --script app_flow_lifecycle_test.gd","godot --headless --path project --script p10_test.gd"],"reason":"前四项退出码 0p10_test 失败 3 项:phase=game 后 Loading 遮罩仍可见、无 SceneTree 构造 char-select 调用空 tree create_timer、选人和重连回放断言失败。成功测试不能证明 40250 的 PHASE_CLOSE、失败重试、deadline、密码清理、可选安全包和真实服务端包序。"}
{"time":"2026-09-20T22:10:00Z","event":"audit_finding","id":"movement.keyboard.motion","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInputKeyboard.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseMovement.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseMotion.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceMotion.cpp","project/player_controller.gd","project/net_play.gd","project/net_world.gd","audit/contracts/movement.keyboard-motion.md"],"reason":"完成 WASD/方向/动作第二轮核对:输入优先级、KeyUp、失焦清理、跨 PI 转向和直立约束有对应回归;但 40250 固定 300 像素目标+MSA 根运动、动作事件边沿、锁门恢复、相机旋转副作用和真实模型生命周期仍不等价,合同继续 PARTIAL。"}
{"time":"2026-09-20T22:10:00Z","event":"test_run","id":"movement.keyboard.motion","result":"PARTIAL","tests":["godot --headless --path project --script test_wasd_steering_parity.gd","godot --headless --path project --script test_no_auto_move_regression.gd","godot --headless --path project --script player_motion_test.gd","godot --headless --path project --script keyboard_motion_timeline_test.gd"],"reason":"WASD steering、无自动移动和键盘时序测试退出码 0player_motion_test 打印 PASS 但退出码 139,并报告 6 个 ObjectDB 泄漏,因此不能计为干净 PASS。通过项不覆盖根运动、动作事件、受击/技能/情绪锁门、相机副作用或真实模型退出安全。"}
{"time":"2026-09-20T22:30:00Z","event":"audit_finding","id":"combat.death.exp_drop","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseBattle.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonEffectModule.cpp","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","project/net_play.gd","project/net_world.gd","project/player_controller.gd","project/ui/death_ui.gd","project/ui/ground_items.gd","audit/contracts/combat.death-exp-drop.md"],"reason":"完成死亡/经验/掉落第二轮核对:POINT_EXP.amount 一次性经验和 FLY_EXP 视觉分离保持正确,基础死亡/掉落回归通过;但主角 GC_DEAD 未统一接入 stop/自动攻击/GameOver/复活,POINT_* effect/金币/属性技能刷新和真实包序仍不等价,合同继续 PARTIAL。"}
{"time":"2026-09-20T22:30:00Z","event":"test_run","id":"combat.death.exp_drop","result":"PASS","tests":["godot --headless --path project --script test_combat_death_pickup_entry_parity.gd","godot --headless --path project --script mob_death_drop_test.gd","godot --headless --path project --script combat_parity_test.gd","godot --headless --path project --script playable_combat_test.gd","godot --headless --path project --script gamescene_test.gd","build/extension/net_state_queue_test"],"reason":"六项回归均退出码 0;通过项只覆盖局部战斗门、死亡怪物、掉落、经验增量和 map reset,不覆盖主角 GC_DEAD 门禁、完整 POINT_* 副作用、重复/乱序/复活清理及真实服务器攻击→死亡→经验→掉落包序。"}
{"time":"2026-09-20T22:50:00Z","event":"audit_finding","id":"network.security_encoding","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseHandShake.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseLogin.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseSelect.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/NetStream.cpp","../40250/Server Client TMP4/ClientVS22/source/EterBase/cipher.cpp","../40250/Server Client TMP4/ClientVS22/source/EterBase/tea.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLocale/StringCodec.cpp","extension/src/net/classic/classic_stream.cpp","extension/src/net/classic/classic_cipher.cpp","extension/src/net/classic/sequence_table.h","extension/src/net/text_codec.h","audit/contracts/network.security-encoding.md"],"reason":"完成握手时钟、DH2/CTR、sequence、TEA、Hybrid/Panama、locale 和定长文本第二轮核对:局部改进加密/分帧回归通过,但 HANDSHAKE_OK 二次全局校准、flush 时加密、legacy TEA 主链、可选资源/反作弊、Windows codepage 和 reference sequence hash 仍不等价,合同继续 PARTIAL。"}
{"time":"2026-09-20T22:50:00Z","event":"test_run","id":"network.security_encoding","result":"PASS","tests":["build/extension/net_classic_cipher_test","build/extension/net_classic_encstream_test","build/extension/net_text_codec_test"],"reason":"三项测试均退出码 0;证明当前端 DH2/CTR、stream key agreement/缓存密文、sequence trailer 和 UTF-8 截断自洽,不覆盖 40250 server fixture、HANDSHAKE_OK 二次校准、legacy TEA、Hybrid/Panama/HS/XTrap、Windows codepage 或完整 sequence 表逐项校验。"}
{"time":"2026-09-20T23:10:00Z","event":"audit_finding","id":"network.character_select.create_delete","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseLogin.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseSelect.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStream.cpp","extension/src/net/classic/classic_parser.cpp","extension/src/net/classic/classic_session.cpp","extension/src/net/m2_client.cpp","project/app_flow.gd","project/ui/char_select_screen.gd","audit/contracts/network.character-select.md"],"reason":"完成角色列表/帝国/创建/删除/改名/DirectEnter 第二轮核对:4 槽 happy path 和 CRUD loopback 通过,但 legacy 3 槽不保留 slot 3、DirectEnter PHASE_SELECT 仍多发普通选择包、越界创建和未命中 PID 错误码不同、帝国写入时点/locale 字节/重复进入保护未等价,合同继续 PARTIAL。"}
{"time":"2026-09-20T23:10:00Z","event":"test_run","id":"network.character_select.create_delete","result":"PASS","tests":["godot --headless --path project --script char_create_delete_test.gd","godot --headless --path project --script test_intro_select_parity.gd","build/extension/net_classic_session_test","build/extension/net_loopback_test"],"reason":"四项回归均退出码 0;通过项覆盖 4 槽 UI、创建/删除/改名、普通选人和 loopback 主路径,不覆盖真实 3 槽固定第 4 空槽、DirectEnter 包序、越界/未命中失败回调、locale codepage、重复进入和中断清理。"}
{"time":"2026-09-20T23:35:00Z","event":"audit_finding","id":"item.inventory_equipment_state","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ItemData.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ItemManager.cpp","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_session.cpp","project/ui/inventory_ui.gd","project/ui/equip_model.gd","audit/contracts/item.inventory-equipment-state.md"],"reason":"完成背包/装备状态第二轮核对:Set/Update/Del、经典物品帧、槽位边界和装备 UI 回归通过;但 native 操作缺 __CanActMainInstance/交易/商店/攻击中门与物品音效,未知 vnum 可进入 storeSet2 高亮、Update 双刷新、空槽字段 API 和 Loading 重建仍不等价,合同继续 PARTIAL。"}
{"time":"2026-09-20T23:35:00Z","event":"test_run","id":"item.inventory_equipment_state","result":"PARTIAL","tests":["build/extension/net_bounds_test","build/extension/net_entity_test","build/extension/net_classic_session_test","godot --headless --path project --script inventory_ui_test.gd","godot --headless --path project --script equip_model_test.gd","godot --headless --path project --script item_tooltip_test.gd","godot --headless --path project --script view_equipment_ui_test.gd"],"reason":"七项回归均退出码 0view_equipment_ui_test 退出时报告 5 个 ObjectDB 泄漏。通过项不能证明未知 vnum、操作门控/音效、Set2 highlight、Update 双刷新、空槽 API 和换图/断线重建与 40250 等价。"}
{"time":"2026-09-20T23:55:00Z","event":"audit_finding","id":"item.consumable_action","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerModule.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonItem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Packet.h","project/consumable_system.gd","project/item_split_system.gd","project/ui/quickbar.gd","project/ui/inventory_ui.gd","project/ui/shop_ui.gd","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_session.cpp","extension/src/net/entity_store.cpp","audit/contracts/item.consumable-action.md"],"reason":"完成消耗品、快捷栏、堆叠拆分和 NPC 出售的逐函数/协议第二轮审计:40250 的快捷栏由 CG 请求和 GC_QUICKSLOT_* 回包驱动,物品使用/移动/出售先经过 CanAct 与装备/交易/商店/攻击门并以服务器回包刷新;当前端仍有快捷栏乐观 _state、本地消耗品脚本未接反馈、ItemSplitSystem 直接改 Array、quick_sell_item 直接加金币清槽,以及正式 UI 与本地旁路两套权威路径。complex_item_drop_test 购买模式拒绝拖放检查失败,其他局部测试通过但不覆盖真实服务器回包。合同继续 PARTIAL。"}
{"time":"2026-09-20T23:55:00Z","event":"test_run","id":"item.consumable_action","result":"PARTIAL","tests":["godot --headless --path project --script test_consumables_parity.gd","godot --headless --path project --script test_item_split_parity.gd","godot --headless --path project --script test_taskbar_quickslot_parity.gd","godot --headless --path project --script complex_item_drop_test.gd","godot --headless --path project --script netplay_test.gd"],"reason":"test_consumables_parity 36/36、test_item_split_parity 19/19、test_taskbar_quickslot_parity 34/34 和 netplay_test 均退出码 0quickslot 测试退出时有 91 CanvasItem RID、221 ObjectDB、3 个资源和文本 RID 泄漏。complex_item_drop_test 退出码 1,购买模式下卖出目标拒绝拖放检查失败。因此局部断言通过不能升级为 40250 等价,合同保持 PARTIAL。"}
{"time":"2026-09-21T00:15:00Z","event":"audit_finding","id":"item.drop_pickup","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonItem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInputMouse.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonTextTail.cpp","extension/src/net/classic/classic_parser.cpp","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","project/ui/ground_items.gd","project/net_play.gd","project/player_controller.gd","audit/contracts/item.drop-pickup.md"],"reason":"完成地面掉落、归属、模型、名条、点选和拾取的逐函数/协议第二轮审计:基础 add/del/owner/pickup 包与距离/节流/UI 回归通过,但当前仍接受未知 vnum、使用通用占位模型、缺真实 drop model/effect/sound/animation、模型相交拾取、party/anti-flag 权限和 native action gateNetPlay 与 GroundItems 还有双距离层,成功/失败回包顺序未闭合。合同继续 PARTIAL。"}
{"time":"2026-09-21T00:15:00Z","event":"test_run","id":"item.drop_pickup","result":"PARTIAL","tests":["godot --headless --path project --script test_ground_pickup_parity.gd","godot --headless --path project --script mob_death_drop_test.gd","godot --headless --path project --script p2b_test.gd","godot --headless --path project --script text_tail_arrange_test.gd","godot --headless --path project --script test_drop_and_cursor_parity.gd","build/extension/net_entity_test","build/extension/net_classic_session_test"],"reason":"五项 Godot 测试和两项 native 测试均退出码 0;p2b_test 退出时报告 2 个 ObjectDB 泄漏。通过项不能证明未知 vnum、真实 item drop resource、模型相交、party/anti-flag、native action gate 或 CG_ITEM_PICKUP 后 GC_DEL→ITEM_GET/SET/UPDATE 包序,合同保持 PARTIAL。"}
{"time":"2026-09-21T00:35:00Z","event":"audit_finding","id":"item.refine_socket_costume","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamModule.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ItemData.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBase.cpp","project/ui/refine_ui.gd","project/item_attr_system.gd","project/item_enchant_system.gd","project/jewelry_socket_system.gd","project/costume_system.gd","project/costume_attr_transfer_system.gd","project/wardrobe_transmog_system.gd","project/refine_effect_system.gd","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_parser.cpp","extension/src/net/classic/classic_session.cpp","audit/contracts/item.refine-socket-costume.md"],"reason":"完成强化、旧/新版 refine cue、属性、socket、时装和幻化的逐函数/协议第二轮审计:parser 已分别支持 95/119 两种 refine layout,基础 refine/DS 包和局部 UI 测试通过;但 M2Client::refine 拒绝 255,255 取消 sentinel,本地属性/socket/costume/transmog 旁路仍直接改字典/金币/计时,未闭合服务器 item/point/affect/actor 回包,幻化属于当前端自定义扩展。合同继续 PARTIAL。"}
{"time":"2026-09-21T00:35:00Z","event":"test_run","id":"item.refine_socket_costume","result":"PARTIAL","tests":["godot --headless --path project --script test_refine_parity.gd","godot --headless --path project --script test_refine_effect_parity.gd","godot --headless --path project --script test_item_attr_parity.gd","godot --headless --path project --script test_item_enchant_manager_parity.gd","godot --headless --path project --script test_jewelry_socket_parity.gd","godot --headless --path project --script test_costume_system_parity.gd","godot --headless --path project --script test_costume_attr_transfer_parity.gd","godot --headless --path project --script test_wardrobe_transmog_parity.gd","godot --headless --path project --script guild_refine_test.gd","build/extension/net_classic_session_test","build/extension/net_entity_test"],"reason":"所有列出的 Godot/native 回归均退出码 0;断言覆盖的是 UI、本地属性/socket/costume/transmog helper、基础 refine/DS 包和 cue。未覆盖 255,255 native 取消发送、旧包真实字节 fixture、refine 后 item/point/affect/actor 顺序、服务器拒绝/重复/断线/模型清理,因此合同保持 PARTIAL。"}
{"time":"2026-09-21T00:55:00Z","event":"audit_finding","id":"npc.dialog_shop","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonShop.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInputMouse.cpp","../40250/Server Client TMP4/ClientVS22/Client/EterPythonLib/uishop.py","../40250/Server Client TMP4/ClientVS22/Client/EterPythonLib/uiprivateshopbuilder.py","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_session.cpp","project/net_play.gd","project/ui/shop_ui.gd","project/ui/private_shop_ui.gd","audit/contracts/npc.dialog-shop.md"],"reason":"完成 NPC 对话、普通/多货架商店、买卖、个人商店招牌和摆摊的第二轮审计:基础 NPC/Shop/PrivateShop 包与局部 UI 测试通过,但 EntityStore 多货架增量只接受 0..39 且更新 tab 0,购买模式拖放仍可出售,shop sign 未完整路由到 SendOnClickPacket,自己的/他人个人商店分支与本地金币库存旁路未统一。合同继续 PARTIAL。"}
{"time":"2026-09-21T00:55:00Z","event":"test_run","id":"npc.dialog_shop","result":"PARTIAL","tests":["godot --headless --path project --script test_npc_shop_parity.gd","godot --headless --path project --script test_npc_shop_flow.gd","godot --headless --path project --script test_npc_dialog_shop_ui_parity.gd","godot --headless --path project --script private_shop_ui_test.gd","godot --headless --path project --script test_private_shop_bundle_parity.gd","godot --headless --path project --script shop_rules_test.gd","godot --headless --path project --script p8_test.gd","godot --headless --path project --script complex_item_drop_test.gd","build/extension/net_classic_session_test","build/extension/net_entity_test"],"reason":"除 complex_item_drop_test 外其余 Godot/native 回归均退出码 0complex_item_drop_test 仍有 1 项购买模式拒绝出售拖放检查失败。通过项主要为 fake client、本地 helper 或基础包测试,不覆盖真实 START_EX 全局更新、shop sign 点击、自己的摊位分支、服务端错误/售罄/断线和回包顺序,合同保持 PARTIAL。"}
{"time":"2026-09-21T01:15:00Z","event":"audit_finding","id":"social.chat_text_tail","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonChat.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonTextTail.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Packet.h","project/ui/chat_ui.gd","project/whisper_chat_system.gd","project/chat_tail.gd","project/text_tail.gd","project/net_world.gd","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","audit/contracts/social.chat-text-tail.md"],"reason":"完成聊天、私聊、气泡和尾标第二轮审计:基础 GC_CHAT/GC_WHISPER 与局部 UI/尾标测试通过,但 ChatUI 的 whisper mode 映射错误、发送失败仍本地回显并关闭、独立 WhisperChatSystem 未接 live UI,未知 VID/NOTICE/BIG_NOTICE/表情/过滤/跨帝国文字分支缺失,Label3D 仍不是真实 CGraphicText 尾标链。合同继续 PARTIAL。"}
{"time":"2026-09-21T01:15:00Z","event":"test_run","id":"social.chat_text_tail","result":"PARTIAL","tests":["godot --headless --path project --script chat_test.gd","godot --headless --path project --script chat_tail_test.gd","godot --headless --path project --script text_tail_test.gd","godot --headless --path project --script text_tail_arrange_test.gd","godot --headless --path project --script name_tail_layout_test.gd","godot --headless --path project --script guild_mark_tail_test.gd","godot --headless --path project --script test_whisper_chat_parity.gd","godot --headless --path project --script chat_mobile_ui_test.gd","godot --headless --path project --script test_chat_hyperlink_dice_parity.gd","build/extension/net_entity_test","build/extension/net_classic_session_test"],"reason":"全部列出的测试均退出码 0,其中 test_whisper_chat_parity 26/26、test_chat_hyperlink_dice_parity 23/23;结果主要证明局部 helper/UI/基础包行为,未覆盖 whisper mode 0..5/0xFF、未知 VID、NOTICE/BIG_NOTICE、过滤/表情、发送失败回显和真实字体尾标,合同保持 PARTIAL。"}
{"time":"2026-09-21T01:35:00Z","event":"audit_finding","id":"social.party_guild_messenger","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameActor.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonGuild.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonMessenger.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/GuildMarkDownloader.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/GuildMarkUploader.cpp","project/party_management_system.gd","project/guild_skill_system.gd","project/guild_war_system.gd","project/messenger_system.gd","project/guild_mark_uploader_system.gd","project/ui/party_ui.gd","project/ui/guild_ui.gd","project/ui/friend_ui.gd","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_mark_client.cpp","audit/contracts/social.party-guild-messenger.md"],"reason":"完成组队、公会、好友/Messenger、会徽下载上传和战争/技能的第二轮审计:native live 主干和局部 UI/基础协议测试通过,但本地 party/guild skill/war/messenger/mark helper 仍可绕过服务器直接成功,好友/会徽缓存有两套状态源,真实权限拒绝、重连清理、mark 分片/CRC/损坏恢复和角色刷新时序未闭合。合同继续 PARTIAL。"}
{"time":"2026-09-21T01:35:00Z","event":"test_run","id":"social.party_guild_messenger","result":"PARTIAL","tests":["godot --headless --path project --script test_party_management_parity.gd","godot --headless --path project --script test_messenger_parity.gd","godot --headless --path project --script test_guild_mark_uploader_parity.gd","godot --headless --path project --script guild_mark_test.gd","godot --headless --path project --script guild_mark_tail_test.gd","godot --headless --path project --script test_guild_war_parity.gd","godot --headless --path project --script test_guild_war_observer_arena_parity.gd","godot --headless --path project --script test_guild_skill_parity.gd","godot --headless --path project --script guild_creation_ui_test.gd","godot --headless --path project --script test_privilege_empire_guild_parity.gd","godot --headless --path project --script p8_test.gd","build/extension/net_entity_test","build/extension/net_classic_session_test"],"reason":"所有列出的 Godot/native 测试均退出码 0;其中 party 30/30、messenger 27/27、mark uploader 12/12、guild war 25/25、observer 21/21、guild skill 31/31。通过项主要为本地 helper/UI/基础包,不覆盖真实 GC 权限拒绝、重连/离会清理、mark server 分片/CRC/坏块和角色刷新顺序,合同保持 PARTIAL。"}
{"time":"2026-09-21T01:55:00Z","event":"audit_finding","id":"social.exchange_safebox","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonExchange.cpp","../40250/Server Client TMP4/ClientVS22/Client/EterPythonLib/uiexchange.py","../40250/Server Client TMP4/ClientVS22/Client/EterPythonLib/uisafebox.py","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_session.cpp","project/ui/exchange_ui.gd","project/ui/safebox_ui.gd","project/ui/mall_ui.gd","project/player_trade_exchange_system.gd","project/safebox_storage_keeper_system.gd","audit/contracts/social.exchange-safebox.md"],"reason":"完成交易、仓库、商城、密码和安全锁第二轮审计:native/store/UI 主干与局部回归通过,但 native exchange 缺 CanAct/交易状态门,本地 helper 仍直接结算物品金币与密码/库存,exchange pending/取消先本地关闭,真实 GC_END、SET/DEL、错误、断线/乱序回滚未闭合。"}
{"time":"2026-09-21T01:55:00Z","event":"test_run","id":"social.exchange_safebox","result":"PARTIAL","tests":["godot --headless --path project --script test_player_trade_exchange_parity.gd","godot --headless --path project --script test_safebox_mall_parity.gd","godot --headless --path project --script test_safebox_storage_keeper_parity.gd","godot --headless --path project --script shop_cube_mall_test.gd","godot --headless --path project --script test_mall_affect_parity.gd","godot --headless --path project --script popup_windows_parity_test.gd","godot --headless --path project --script test_security_lock_parity.gd","build/extension/net_entity_test","build/extension/net_classic_session_test","godot --headless --path project --script complex_item_drop_test.gd"],"reason":"除 complex_item_drop_test 外其余 Godot/native 回归均退出码 0;交易 28/28、Safebox/Mall 37/37、本地 keeper 37/37、安全锁 48/48。complex_item_drop_test 仍有购买模式拖放出售失败检查。局部测试不能证明真实 GC_EXCHANGE/SAFEBOX/MALL 错误、断线、乱序、回滚和音效顺序,合同保持 PARTIAL。"}
{"time":"2026-09-21T02:15:00Z","event":"audit_finding","id":"quest.quest_event_navigation","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonQuest.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonEventManager.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonMiniMap.cpp","../40250/Server Client TMP4/ClientVS22/Client/EterPythonLib/uiquest.py","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","project/ui/quest_dialog.gd","project/ui/quest_log.gd","project/ui/atlas_ui.gd","project/game_scene.gd","project/biologist_quest_system.gd","project/event_manager_system.gd","audit/contracts/quest.quest-event-navigation.md"],"reason":"完成任务信息、脚本事件、确认/输入/选择、HUD、地图信号、Atlas、镜幕和本地任务 helper 第二轮审计:基础 42 标签/quest/script 包可用,但 EntityStore END 不删除、QuestLog 计时依赖可见窗口、native script_button 拒绝负数任务索引、DONE/ESC 语义错误、RUN_CINEMA 无消费者、Atlas 未消费任务 signal,且本地任务/活动 helper 不是 40250 客户端 authority。合同继续 PARTIAL。"}
{"time":"2026-09-21T02:15:00Z","event":"test_run","id":"quest.quest_event_navigation","result":"PARTIAL","tests":["godot --headless --path project --script quest_test.gd","godot --headless --path project --script quest_event_test.gd","godot --headless --path project --script test_quest_dialog_parity.gd","godot --headless --path project --script test_quest_hud_parity.gd","godot --headless --path project --script quest_curtain_test.gd","godot --headless --path project --script atlas_test.gd","godot --headless --path project --script test_atlas_navigation_parity.gd","godot --headless --path project --script test_map_name_shower_parity.gd","godot --headless --path project --script test_minimap_radar_parity.gd","godot --headless --path project --script test_biologist_quest_parity.gd","godot --headless --path project --script test_event_manager_parity.gd","build/extension/net_entity_test","build/extension/net_classic_session_test","build/extension/net_classic_wire_test"],"reason":"所有列出的测试均退出码 0quest_dialog 45/45、quest_hud 19/19、生物学家 28/28、活动 24/24。但 test_quest_dialog_parity 的 DONE 断言把错误的 script_answer(254) 当成功,fake HUD 未经过 native 负数 script_button 拒绝;因此不能升级为 40250 等价,合同保持 PARTIAL。"}
{"time":"2026-09-21T02:35:00Z","event":"audit_finding","id":"world.dungeon_activity","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonDungeonInfo.py","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","project/dungeon_state.gd","project/ui/dungeon_result_ui.gd","project/world_boss_system.gd","project/dungeon_ranking_system.gd","project/spider_dungeon_system.gd","project/flame_dungeon_razador_system.gd","project/endless_spire_dungeon_system.gd","audit/contracts/world.dungeon-activity.md"],"reason":"完成地下城/活动第二轮审计:GC_DUNGEON 目标状态、坐标转换、10,000 cm Manhattan 到达阈值和 20 秒 alarm 状态接近参考;但 alarm_requested 没有实际 compass/effect 资源消费者,DUNGEON_RESULT 缺少真实 live 回包时序证据,Boss/排行/副本 helper 是当前端本地 authority,且拒绝、乱序、断线/切图清理未闭合。合同保持 PARTIAL。"}
{"time":"2026-09-21T02:35:00Z","event":"test_run","id":"world.dungeon_activity","result":"PARTIAL","tests":["godot --headless --path project --script dungeon_state_test.gd","godot --headless --path project --script dungeon_result_test.gd","godot --headless --path project --script test_dungeon_ranking_parity.gd","godot --headless --path project --script test_spider_dungeon_parity.gd","godot --headless --path project --script test_spider_dungeon_key_parity.gd","godot --headless --path project --script test_flame_dungeon_razador_parity.gd","godot --headless --path project --script test_endless_spire_dungeon_parity.gd","build/extension/net_entity_test","build/extension/net_classic_session_test","build/extension/net_classic_wire_test"],"reason":"所有列出的 Godot/native 测试均退出码 0;本地断言包含排行 30/30、蜘蛛 32/32、钥匙 34/34、火焰 31/31、无限塔 22/22。通过项验证当前端状态/helper,不覆盖实际 compass.mse 消费、live DUNGEON_RESULT、服务器拒绝和重连清理,合同保持 PARTIAL。"}
{"time":"2026-09-21T02:55:00Z","event":"audit_finding","id":"world.fishing_mining","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstance.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonMiniMap.cpp","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_session.cpp","project/fishing_mining_system.gd","project/fishing_rod_reel_system.gd","project/fishing_cooking_camp_system.gd","project/mining_refinery_smelt_system.gd","project/fishing_water_test.gd","project/water_reference_test.gd","project/netbridge_test.gd","audit/contracts/world.fishing-mining.md"],"reason":"完成钓鱼/采矿第二轮审计:600cm/10度水面扫描、500ms 取消节流和 fishing/dig 协议骨架存在;但持竿/持镐 live 门控、REACT 的 IsFishing 条件、DIG count 多动作队列、资源/音效和服务端拒绝回滚未闭合,收益/烹饪/营火/熔炼/库存仍由本端 custom authority 直接结算。netbridge_test 仍失败 3 项并有 5 个 ObjectDB 泄漏。合同保持 PARTIAL。"}
{"time":"2026-09-21T02:55:00Z","event":"test_run","id":"world.fishing_mining","result":"PARTIAL","tests":["godot --headless --path project --script test_fishing_mining_parity.gd","godot --headless --path project --script test_fishing_rod_reel_parity.gd","godot --headless --path project --script test_fishing_cooking_camp_parity.gd","godot --headless --path project --script test_mining_refinery_smelt_parity.gd","godot --headless --path project --script fishing_water_test.gd","godot --headless --path project --script water_reference_test.gd","godot --headless --path project --script netplay_test.gd","godot --headless --path project --script netbridge_test.gd","godot --headless --path project --script combat_fx_test.gd","godot --headless --path project --script chat_test.gd","build/extension/net_entity_test","build/extension/net_classic_session_test","build/extension/net_classic_wire_test"],"reason":"除 netbridge_test 外列出的回归均退出码 0;钓鱼 26/26、鱼竿 33/33、烹饪营火 23/23、采矿熔炼 21/21,水参考 failures=0。netbridge_test 失败 3 项(实体节点、mount 子节点、主实体可见性)且有 5 个 ObjectDB 泄漏,因此不能升级为统一实现,合同保持 PARTIAL。"}
{"time":"2026-09-21T03:15:00Z","event":"audit_finding","id":"world.mount_pet_polymorph","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstance.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","project/net_world.gd","project/net_play.gd","project/equip_model.gd","project/horse_system.gd","project/horse_combat_system.gd","project/horse_level_growth_system.gd","project/mounted_combat_skill_system.gd","project/pet_companion_system.gd","project/classic_pet_system.gd","project/polymorph_system.gd","project/polymorph_marble_system.gd","audit/contracts/world.mount-pet-polymorph.md"],"reason":"完成坐骑、宠物、变身第二轮审计:mount_vnum parser/store/signal、部分动作模式/旋转速度/攻击等级门存在;但没有找到实际 horse/saddle model attachGC_MOUNT 位置/下马/重连清理未闭合,变身 native affect→shape/装备遮挡链缺失,宠物及马匹成长/耐力/技能/变身收益由本地 helper 直接结算而非 40250 client authority。合同保持 PARTIAL。"}
{"time":"2026-09-21T03:15:00Z","event":"test_run","id":"world.mount_pet_polymorph","result":"PARTIAL","tests":["godot --headless --path project --script test_mount_horse_parity.gd","godot --headless --path project --script test_horse_combat_parity.gd","godot --headless --path project --script test_horse_level_growth_parity.gd","godot --headless --path project --script test_mounted_combat_skill_parity.gd","godot --headless --path project --script test_pet_companion_parity.gd","godot --headless --path project --script test_classic_pet_parity.gd","godot --headless --path project --script test_polymorph_parity.gd","godot --headless --path project --script test_polymorph_marble_parity.gd","godot --headless --path project --script equip_rules_test.gd","godot --headless --path project --script test_battle_arena_duel_parity.gd","godot --headless --path project --script player_move_test.gd","godot --headless --path project --script netplay_test.gd","godot --headless --path project --script netbridge_test.gd","build/extension/net_entity_test","build/extension/net_classic_session_test"],"reason":"坐骑/马战/成长/马上技能/宠物/变身相关回归均退出码 0;netbridge_test 仍失败 3 项并有 5 个 ObjectDB 泄漏。局部测试验证当前端 helper 和部分字段映射,不覆盖实际模型挂接、GC_MOUNT 位置、native polymorph affect、服务器拒绝、乱序和重连清理,合同保持 PARTIAL。"}
{"time":"2026-09-21T03:35:00Z","event":"audit_finding","id":"render.model_attachment","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/ThingInstance.cpp","../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/LODController.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceAttach.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/RaceData.cpp","extension/src/metin2_model.cpp","extension/src/metin2_anim.cpp","extension/src/gr2_bridge.cpp","project/ui/player_view.gd","project/ui/remote_player_view.gd","project/ui/mob_view.gd","project/ui/equip_model.gd","audit/contracts/render.model-attachment.md"],"reason":"完成模型/LOD/骨骼/装备挂点第二轮审计:基础模型、装备和 bounds 断言存在,但 40250 的 500/1500/2500cm 多 LOD 控制器与当前 [18,42,90]m 单骨骼网格替换不等价;03150 双手左手挂点失败,动作缓存失败,真实模型测试多次 exit 139/ObjectDB 泄漏。合同保持 PARTIAL。"}
{"time":"2026-09-21T03:35:00Z","event":"test_run","id":"render.model_attachment","result":"PARTIAL","tests":["godot --headless --path project --script weapon_attach_test.gd","godot --headless --path project --script gpu_lod_attachment_test.gd","godot --headless --path project --script gpu_pose_bounds_test.gd","godot --headless --path project --script race_motion_assembly_test.gd","godot --headless --path project --script equip_model_test.gd","godot --headless --path project --script remote_player_test.gd","godot --headless --path project --script mob_view_test.gd","godot --headless --path project --script animation_cache_test.gd","build/formats/formats_map_test","build/formats/formats_msa_test","build/formats/formats_msm_test","build/extension/net_bounds_test","build/extension/net_entity_test","build/extension/net_classic_session_test","build/extension/net_classic_wire_test"],"reason":"weapon_attach 失败 1 项且 exit 139/52 ObjectDBGPU LOD/pose/race 断言为 0 但 exit 139,泄漏 48/48/82 ObjectDBremote/mob 断言通过但各泄漏 8 ObjectDBanimation_cache 失败 2 项且 exit 139。基础 formats/native 测试退出码 0,但无 M2_ASSETS 时 live A1 断言跳过,合同保持 PARTIAL。"}
{"time":"2026-09-21T03:55:00Z","event":"audit_finding","id":"render.effect_particle_motion","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/GameLib/RaceMotionData.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceMotionEvent.cpp","../40250/Server Client TMP4/ClientVS22/source/EffectLib/EffectManager.cpp","formats/msa.cpp","formats/msa.h","extension/src/metin2_anim.cpp","project/fx/effect_player.gd","project/fx/mde.gd","project/fx/mse.gd","project/fx/motion_effect_anchor.gd","project/fx/target_effect_anchor.gd","project/game_scene.gd","project/ui/remote_player_view.gd","project/ui/mob_view.gd","project/net_world.gd","audit/contracts/render.effect-particle-motion.md"],"reason":"完成动作事件/粒子/飞行物第二轮审计:MDE/MSE 基础解析、粒子曲线和本地主角基础挂点可用,但 MotionEvent 专用字段不完整,远端 PC/NPC/Mob 未统一消费动作事件,type 4/7/8/9 生产分支缺失,type 6 未形成等价 .fly 链;motion anchor 断言虽为 0 仍 exit 139 并泄漏 6 ObjectDB。合同保持 PARTIAL。"}
{"time":"2026-09-21T03:55:00Z","event":"test_run","id":"render.effect_particle_motion","result":"PARTIAL","tests":["godot --headless --path project --script fx_test.gd","godot --headless --path project --script effect_playback_test.gd","godot --headless --path project --script target_effect_test.gd","godot --headless --path project --script skill_fx_test.gd","godot --headless --path project --script effect_color_test.gd","godot --headless --path project --script effect_emission_test.gd","godot --headless --path project --script effect_faces_test.gd","godot --headless --path project --script effect_lie_test.gd","godot --headless --path project --script effect_random_rotation_test.gd","godot --headless --path project --script effect_render_regression_test.gd","godot --headless --path project --script effect_rotation_test.gd","godot --headless --path project --script effect_scale_test.gd","godot --headless --path project --script effect_space_test.gd","godot --headless --path project --script effect_surface_test.gd","godot --headless --path project --script effect_texture_animation_test.gd","godot --headless --path project --script motion_effect_anchor_test.gd"],"reason":"除 motion_effect_anchor_test 外各项无断言失败;surface/texture headless 像素检查跳过。motion_effect_anchor 断言 0 failures 但 exit 139 且泄漏 6 ObjectDB,不能视为稳定通过;基础通过项不覆盖 type 4/6/7/8/9、远端 Actor 分派和跨图清理,合同保持 PARTIAL。"}
{"time":"2026-09-21T04:15:00Z","event":"audit_finding","id":"world.terrain_water_collision","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoor.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/AreaTerrain.cpp","../40250/Server Client TMP4/ClientVS22/source/PRTerrainLib/Terrain.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoorWater.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/AttributeInstance.cpp","formats/terrain_files.cpp","formats/terrain_mesh.cpp","extension/src/metin2_world.cpp","extension/src/water_builder.cpp","project/player_controller.gd","project/net_world.gd","audit/contracts/world.terrain-water-collision.md"],"reason":"完成地形/水面/属性/拾取/碰撞第二轮审计:高度插值、桥面取高、属性、水图和水面结构继续接近参考;但当前 ray_ground 未统一静态对象 Picking 与 5/10/100cm 自适应射线,水层高度未进入抛竿目标,高半字节属性、streaming 延迟加载和双碰撞源未闭合,点击/飞行测试仍有泄漏或 exit 139。合同保持 PARTIAL。"}
{"time":"2026-09-21T04:15:00Z","event":"test_run","id":"world.terrain_water_collision","result":"PARTIAL","tests":["godot --headless --path project --script test_bridge_height_parity.gd","godot --headless --path project --script test_all_map_height_probe.gd","godot --headless --path project --script water_reference_test.gd","godot --headless --path project --script fishing_water_test.gd","godot --headless --path project --script test_click_target_effect_parity.gd","godot --headless --path project --script player_move_test.gd","godot --headless --path project --script test_skill_ground_fix.gd","godot --headless --path project --script fly_target_bounds_test.gd","build/formats/formats_map_test","build/extension/net_bounds_test","build/extension/net_entity_test","build/extension/net_classic_session_test","build/extension/net_classic_wire_test"],"reason":"桥高、全图高度、水参考、钓鱼水面、移动和技能贴地断言通过;click_target 断言通过但有 3 ObjectDB/1 resource 泄漏,fly_target_bounds 断言通过但 exit 139/48 ObjectDB。formats/native 基础测试退出码 0,但无 M2_ASSETS 时 live A1 断言跳过,合同保持 PARTIAL。"}
{"time":"2026-09-21T04:35:00Z","event":"audit_finding","id":"world.environment_weather","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoorRender.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/SnowEnvironment.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/EnvironmentMap.cpp","formats/environment.cpp","extension/src/environment_builder.cpp","extension/src/metin2_world.cpp","project/game_scene.gd","project/fx/weather.gd","project/weather_daynight_system.gd","audit/contracts/world.environment-weather.md"],"reason":"完成环境/天气第二轮审计:.msenv、双方向光、天空/云和基础天气 helper 回归通过;但 filter/lens flare/wind 仍是 metadataGodot depth fog 与参考线性雾不等价,WeatherDayNightSystem 未接入正式 GameScene,单 GPUParticles3D 不等价 SnowEnvironment 池和地图生命周期。合同保持 PARTIAL。"}
{"time":"2026-09-21T04:35:00Z","event":"test_run","id":"world.environment_weather","result":"PARTIAL","tests":["godot --headless --path project --script environment_test.gd","godot --headless --path project --script skybox_test.gd","godot --headless --path project --script p9_test.gd","godot --headless --path project --script test_weather_daynight_parity.gd"],"reason":"environment、skybox、p9 退出码 0;天气昼夜 22/22 通过。但天气测试只覆盖独立 helper,不覆盖正式 GameScene 接入、参考 fog/filter/lens flare/wind 渲染顺序和真实切图清理,合同保持 PARTIAL。"}
{"time":"2026-09-21T04:55:00Z","event":"audit_finding","id":"ui.input_camera_mobile","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInputKeyboard.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInputMouse.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonApplicationCamera.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonApplicationCursor.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonIME.cpp","project/player_controller.gd","project/game_scene.gd","project/game_camera.gd","project/ui/mouse_controller.gd","project/ui/cursor_manager.gd","project/ui/mobile","audit/contracts/ui.input-camera-mobile.md"],"reason":"完成输入/相机/移动端第二轮审计:鼠标、键盘、触屏和安全区基础回归通过;game_camera_test 仍失败默认距离 1550cm、默认俯仰 27°和 RESTORE_CAMERA 三项,输入清理有 ObjectDB/Camera RID 泄漏,IME 仍依赖 LineEdit,未形成 40250 的统一即时输入/相机状态链。合同保持 PARTIAL。"}
{"time":"2026-09-21T04:55:00Z","event":"test_run","id":"ui.input_camera_mobile","result":"PARTIAL","tests":["godot --headless --path project --script mouse_controller_test.gd","godot --headless --path project --script input_key_test.gd","godot --headless --path project --script mobile_gesture_test.gd","godot --headless --path project --script mobile_ui_test.gd","godot --headless --path project --script mobile_window_host_test.gd","godot --headless --path project --script game_camera_test.gd"],"reason":"mouse、mobile gesture/UI/window 和 input_key 的功能断言通过;input_key 有 20 ObjectDB/1 Camera RID 泄漏;game_camera_test 失败 3 项,因此不能升级为统一实现,合同保持 PARTIAL。"}
{"time":"2026-09-21T05:15:00Z","event":"audit_finding","id":"ui.hud_target_minimap_status","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonApplication.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonTextTail.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonMiniMap.cpp","../40250/Server Client TMP4/ClientVS22/Client/EterPythonLib/uitaskbar.py","extension/src/net/m2_client.cpp","project/net_play.gd","project/net_world.gd","project/hud.gd","project/ui/target_board.gd","project/ui/target_ui.gd","project/ui/minimap.gd","project/text_tail.gd","project/text_tail_arrange.gd","project/game_scene.gd","audit/contracts/ui.hud-target-minimap-status.md"],"reason":"完成 HUD/目标框/小地图/尾标第二轮审计:TargetBoard 13/13、minimap 6/6、TextTail/状态/任务栏 helper 通过;但正式 GameScene 未注入唯一 TargetUIHUD 与新 minimap 仍双 owner,小地图 scale/步进与参考不同,quickbar 测试有 221 ObjectDB/91 CanvasItem RID/资源与字体 RID 泄漏。合同保持 PARTIAL。"}
{"time":"2026-09-21T05:15:00Z","event":"test_run","id":"ui.hud_target_minimap_status","result":"PARTIAL","tests":["godot --headless --path project --script test_target_board_parity.gd","godot --headless --path project --script target_board_test.gd","godot --headless --path project --script test_minimap_radar_parity.gd","godot --headless --path project --script p9_test.gd","godot --headless --path project --script text_tail_test.gd","godot --headless --path project --script text_tail_arrange_test.gd","godot --headless --path project --script chat_tail_test.gd","godot --headless --path project --script chat_test.gd","godot --headless --path project --script name_show_test.gd","godot --headless --path project --script char_status_ui_test.gd","godot --headless --path project --script test_taskbar_quickslot_parity.gd","godot --headless --path project --script taskbar_dock_test.gd"],"reason":"列出的 UI/尾标/小地图/状态测试均退出码 0target 13/13、minimap 6/6、quickslot 34/34。但 quickslot 退出时仍有 221 ObjectDB、91 CanvasItem RID、3 resources、56 shaped-text RID、1 font RID 泄漏,且测试未覆盖正式场景重复 owner 和换图清理,合同保持 PARTIAL。"}
{"time":"2026-09-21T05:35:00Z","event":"audit_finding","id":"resource.pack_locale_proto","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/EterPack/EterPackManager.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPackModule.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLocale/StringCodec.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ItemManager.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNonPlayer.cpp","extension/src/pack/eterpack.cpp","extension/src/pack/pack_mount.cpp","extension/src/asset_source.cpp","extension/src/proto/proto.cpp","project/asset_root.gd","project/asset_pack.gd","project/locale.gd","formats/msm.cpp","formats/msa.cpp","audit/contracts/resource.pack-locale-proto.md"],"reason":"完成资源/pack/locale/proto 第二轮审计:自定义 epk、proto fourcc/stride、MSA/MSM、中文文本回归通过;但主运行时未统一接入 PackMount/AssetSourceepk 不互读原生 EterPackpack 优先级/CRC/cache、code page、完整 locale 表和导出包 render 生命周期未闭合。合同保持 PARTIAL。"}
{"time":"2026-09-21T05:35:00Z","event":"test_run","id":"resource.pack_locale_proto","result":"PARTIAL","tests":["build/extension/pack_roundtrip_test","build/extension/proto_test","build/extension/proto_item_layout_test","build/formats/formats_map_test","build/formats/formats_msa_test","build/formats/formats_msm_test","build/formats/formats_combo_table_test","godot --headless --path project --script test_chinese_locale.gd","godot --headless --path project --script skill_test.gd","godot --headless --path project --script package_render_test.gd"],"reason":"pack/proto/formats/native 测试退出码 0,中文 16/16、技能测试通过;proto/live A1 因测试环境缺文件或 M2_ASSETS 未设置而跳过。package_render_test 在直接 headless 入口未结束,已停止,不能计为通过,合同保持 PARTIAL。"}
{"time":"2026-09-21T05:55:00Z","event":"audit_finding","id":"audio.bgm_ambience_3d","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/MilesLib/SoundManager.cpp","../40250/Server Client TMP4/ClientVS22/source/MilesLib/SoundManager3D.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/Area.cpp","project/audio.gd","project/bgm_director.gd","project/game_scene.gd","project/app_lifecycle.gd","formats/area_data.cpp","extension/src/metin2_world.cpp","audit/contracts/audio.bgm-ambience-3d.md"],"reason":"完成音频/BGM/环境声第二轮审计:3D 缩放/限频、A3 ambience、地图 BGM、点唱机 18/18、生命周期和设置回归通过;但动态播放器/Tween 不等价固定实例池与 TMusicInstance 状态机,后台只静音 BGM 未同步 SFX,失败回滚和跨图实例清理未闭合。合同保持 PARTIAL。"}
{"time":"2026-09-21T05:55:00Z","event":"test_run","id":"audio.bgm_ambience_3d","result":"PARTIAL","tests":["godot --headless --path project --script audio_miles_test.gd","godot --headless --path project --script ambience_test.gd","godot --headless --path project --script bgm_test.gd","godot --headless --path project --script test_bgm_jukebox_parity.gd","godot --headless --path project --script app_flow_lifecycle_test.gd","godot --headless --path project --script system_option_ui_test.gd"],"reason":"所有列出的回归均退出码 0,点唱机 18/18;但 FakeAudio/局部 helper 不覆盖真实音频实例状态机、后台 SFX 静音、远端动作音效和快速换图清理,合同保持 PARTIAL。"}
{"time":"2026-09-21T06:15:00Z","event":"audit_finding","id":"lifecycle.platform_release","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/EterLib/MSApplication.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/MSWindow.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonApplication.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/CheckLatestFiles.cpp","project/client_main.gd","project/app_flow.gd","project/app_lifecycle.gd","project/asset_root.gd","project/asset_pack.gd","project/export_presets.cfg","audit/contracts/lifecycle.platform-release.md"],"reason":"完成 Windows/桌面生命周期和发布第二轮审计:AppFlow、DDS 生命周期和 editor 校验通过;但没有 Windows export preset/GDExtension、Win32 消息/异常/CRC 更新链,编辑器校验重建缺失 uid 且提示 Android daemon 不可用,macOS 结果不能替代 Windows 发布通过。合同保持 PARTIAL。"}
{"time":"2026-09-21T06:15:00Z","event":"test_run","id":"lifecycle.platform_release","result":"PARTIAL","tests":["godot --headless --path project --script app_flow_lifecycle_test.gd","godot --headless --path project --script dds_lifecycle_test.gd","godot --headless --path project --editor --quit"],"reason":"AppFlow 和 DDS 测试退出码 0editor --quit 退出码 0editor 自动重建 view_equipment_ui_test.gd.uid,并报告 Android daemon connection refused。当前无 Windows 导出/启动/连接/地图/音频/退出冒烟门禁,合同保持 PARTIAL。"}
{"time":"2026-09-21T06:35:00Z","event":"audit_finding","id":"render.effect_particle_motion","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/EffectLib/EffectData.cpp","../40250/Server Client TMP4/ClientVS22/source/EffectLib/EffectElementBase.cpp","../40250/Server Client TMP4/ClientVS22/source/EffectLib/EffectElementBaseInstance.cpp","../40250/Server Client TMP4/ClientVS22/source/EffectLib/EffectInstance.cpp","../40250/Server Client TMP4/ClientVS22/source/EffectLib/EffectManager.cpp","../40250/Server Client TMP4/ClientVS22/source/EffectLib/EffectMesh.cpp","../40250/Server Client TMP4/ClientVS22/source/EffectLib/EffectMeshInstance.cpp","../40250/Server Client TMP4/ClientVS22/source/EffectLib/EmitterProperty.cpp","../40250/Server Client TMP4/ClientVS22/source/EffectLib/FrameController.cpp","../40250/Server Client TMP4/ClientVS22/source/EffectLib/ParticleInstance.cpp","../40250/Server Client TMP4/ClientVS22/source/EffectLib/ParticleProperty.cpp","../40250/Server Client TMP4/ClientVS22/source/EffectLib/ParticleSystemData.cpp","../40250/Server Client TMP4/ClientVS22/source/EffectLib/ParticleSystemInstance.cpp","../40250/Server Client TMP4/ClientVS22/source/EffectLib/SimpleLightData.cpp","../40250/Server Client TMP4/ClientVS22/source/EffectLib/SimpleLightInstance.cpp","audit/contracts/render.effect-particle-motion.md"],"reason":"本轮逐组核对 EffectLib 活跃核心:参考效果数据同时加载 mesh/particle/light/.mss 声音,EffectManager 管理注册、缓存、固定实例、Update/Render/Destroy,粒子/网格/光源各自有帧和池生命周期。当前端没有完整对应链,静态复核完成但合同保持 PARTIAL。"}
{"time":"2026-09-21T06:35:00Z","event":"audit_finding","id":"render.model_attachment","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/Material.cpp","../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/Mesh.cpp","../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/Model.cpp","../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/ModelInstance.cpp","../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/ModelInstanceUpdate.cpp","../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/Motion.cpp","../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/Thing.cpp","../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/ThingInstance.cpp","../40250/Server Client TMP4/ClientVS22/source/EterGrnLib/LODController.cpp","audit/contracts/render.model-attachment.md"],"reason":"本轮逐组核对 EterGrnLib 活跃核心:Thing/ThingInstance 管理多模型、动作、LOD 注册、Attach/Detach、材质和 boundsLODController 同步各 LOD 的动作/骨骼/材质/shadowModelInstance 更新骨骼世界姿态。当前单骨骼网格替换和 slot_pre 附件未达到同等传播,合同保持 PARTIAL。"}
{"time":"2026-09-21T06:35:00Z","event":"audit_finding","id":"audio.bgm_ambience_3d","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/MilesLib/SoundBase.cpp","../40250/Server Client TMP4/ClientVS22/source/MilesLib/SoundData.cpp","../40250/Server Client TMP4/ClientVS22/source/MilesLib/SoundInstance2D.cpp","../40250/Server Client TMP4/ClientVS22/source/MilesLib/SoundInstance3D.cpp","../40250/Server Client TMP4/ClientVS22/source/MilesLib/SoundInstanceStream.cpp","../40250/Server Client TMP4/ClientVS22/source/MilesLib/SoundManager.cpp","../40250/Server Client TMP4/ClientVS22/source/MilesLib/SoundManager2D.cpp","../40250/Server Client TMP4/ClientVS22/source/MilesLib/SoundManager3D.cpp","../40250/Server Client TMP4/ClientVS22/source/MilesLib/SoundManagerStream.cpp","audit/contracts/audio.bgm-ambience-3d.md"],"reason":"本轮逐组核对 MilesLib 活跃核心:固定 2D/3D/Stream 实例池、pack-backed SoundData 缓存、Play/Stop/位置/速度和音乐实例索引/淡入淡出状态均由 SoundManager 统一管理。当前 Godot 动态播放器/Tween 未闭合这些状态与失败/清理副作用,合同保持 PARTIAL。"}
{"time":"2026-09-21T06:55:00Z","event":"audit_finding","id":"social.chat_text_tail","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamCommand.cpp","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","project/ui/chat_ui.gd","project/net_world.gd","audit/contracts/social.chat-text-tail.md"],"reason":"本轮逐项核对 CHAT_TYPE_COMMAND/ServerCommand 总线:当前端已覆盖 cube、observer、StoneDetect、stamina、mobile、gift、combo、block mode、lover、password/refine/private-shop、emotion/dig 的主要事件及一组 native 测试;但参数错误/未知命令、效果资源创建、全部回调和失败清理没有完整矩阵,ClientCommand 参考实现本身返回 false,合同保持 PARTIAL。"}
{"time":"2026-09-21T07:15:00Z","event":"audit_finding","id":"ui.input_camera_mobile","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/EterLib/Camera.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/Camera.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/IME.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/IME.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/Input.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/msctf.h","project/game_camera.gd","project/ui/chat_ui.gd","audit/contracts/ui.input-camera-mobile.md"],"reason":"完成 EterLib Camera/IME/Input 核心静态核对:参考端存在相机状态/比例缩放、输入法组合与候选/TSF/code-page 回调;当前端固定缩放和 Godot LineEdit 适配仍不等价,game_camera_test 已有 3 项失败,合同保持 PARTIAL。"}
{"time":"2026-09-21T07:15:00Z","event":"audit_finding","id":"resource.pack_locale_proto","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/EterLib/Resource.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/Resource.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/ResourceManager.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/ResourceManager.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/FileLoaderThread.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/FileLoaderThread.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/TextFileLoader.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/TextFileLoader.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/parser.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/parser.h","project/asset_root.gd","project/locale.gd","extension/src/pack/pack_mount.cpp","audit/contracts/resource.pack-locale-proto.md"],"reason":"完成 EterLib Resource/ResourceManager/FileLoaderThread/TextFileLoader/parser 静态核对:参考端闭合 pack-backed cache/CRC/异步/延迟删除/typed-token 链;当前主运行时仍以 loose/assets.zip/PCK + AssetResolver 为主,合同保持 PARTIAL。"}
{"time":"2026-09-21T07:15:00Z","event":"audit_finding","id":"world.terrain_water_collision","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/EterLib/AttributeData.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/AttributeData.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/AttributeInstance.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/CollisionData.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/CollisionData.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/CullingManager.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/CullingManager.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/Decal.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/Decal.h","project/player_controller.gd","project/world.gd","audit/contracts/world.terrain-water-collision.md"],"reason":"完成 EterLib AttributeData/CollisionData/CullingManager/Decal 静态核对:参考端由属性实例、静态碰撞形状、culling 射线/可见性和贴花共同决定结果;当前高度采样、Godot shape 与 AABB/胶囊仍为并行近似,合同保持 PARTIAL。"}
{"time":"2026-09-21T07:15:00Z","event":"audit_finding","id":"world.environment_weather","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/EterLib/SkyBox.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/SkyBox.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/ScreenFilter.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/ScreenFilter.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/LensFlare.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/LensFlare.h","project/environment.gd","project/game_scene.gd","project/skybox.gd","audit/contracts/world.environment-weather.md"],"reason":"完成 EterLib SkyBox/ScreenFilter/LensFlare 静态核对:参考端有天空/云/gradient/transition/render 顺序及独立滤镜/光晕对象;当前 filter/lens flare/wind 主要是 metadata,雾公式和正式天气接入仍不等价,合同保持 PARTIAL。"}
{"time":"2026-09-21T07:15:00Z","event":"audit_finding","id":"social.chat_text_tail","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpText.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpText.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpTextInstance.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpTextInstance.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/TextBar.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/TextBar.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/TextTag.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/TextTag.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpFontTexture.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpFontTexture.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpMarkInstance.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpMarkInstance.h","project/net_world.gd","project/text_tail.gd","audit/contracts/social.chat-text-tail.md"],"reason":"完成 EterLib 文本渲染核心静态核对:参考端由真实字体纹理、字符度量/定位、描边、mark 与池化对象支撑尾标;当前 Label3D/RichTextLabel 和宽度估算只有局部镜像,合同保持 PARTIAL。"}
{"time":"2026-09-21T07:15:00Z","event":"audit_finding","id":"lifecycle.platform_release","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpDevice.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpDevice.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpScreen.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpScreen.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpShadowTexture.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpShadowTexture.h","project/app_lifecycle.gd","project/client_main.gd","audit/contracts/lifecycle.platform-release.md"],"reason":"完成 EterLib GrpDevice/GrpScreen/GrpShadowTexture 静态核对:参考端有 D3D 设备、back buffer、lost/reset、屏幕和阴影纹理状态机;当前 Godot renderer 由引擎托管且无 Windows 验证矩阵,合同保持 PARTIAL。"}
{"time":"2026-09-21T07:40:00Z","event":"audit_finding","id":"movement.motion_resource_events","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstance.h","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceBlend.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceData.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceEvent.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstancePosition.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceRotation.cpp","project/ui/player_view.gd","project/ui/remote_player_view.gd","project/net_play.gd","audit/contracts/movement.motion-resource-events.md"],"reason":"完成 GameLib ActorInstance 核心静态核对:参考端把位置/advancing rotation、alpha blend、WAIT/MOVE/ATTACK/SKILL/HIT/WARP handler、RaceData/ItemData 注册和 moving-skill loop bit 组合到 actor 状态机;当前端常见动作可用但完整 motion queue、父 mode、远端/NPC event consumer 和资源传播未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T07:40:00Z","event":"audit_finding","id":"render.model_attachment","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceData.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstance.h","../40250/Server Client TMP4/ClientVS22/source/GameLib/RaceManager.h","project/ui/player_view.gd","project/ui/remote_player_view.gd","project/ui/equip_model.gd","audit/contracts/render.model-attachment.md"],"reason":"完成 GameLib actor 数据/挂接静态核对:参考 SetRace/SetShape/SetPart/AttachWeapon/UpdateAttachingInstances 传播 base、LOD、hair、weapon/shield、bone、collision/effect;当前 EquipModel/slot_pre 仅是单骨骼适配,03150 左手、LOD 泄漏和动作缓存差异仍在,合同保持 PARTIAL。"}
{"time":"2026-09-21T07:40:00Z","event":"audit_finding","id":"skill.cast_effect_timing","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceEvent.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstance.h","project/game_scene.gd","project/ui/player_view.gd","project/fx/skill_fx.gd","audit/contracts/skill.cast-effect-timing.md"],"reason":"完成 GameLib skill/event 静态核对:参考 OnAttack/OnUseSkill/OnHit/affect 与 motion queue、MotionEventEffectToTarget/Special/Fly 形成逐帧消费者;当前主要接入本地主角 signal,远端/怪物和完整 loop/取消/挂点事件仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T07:40:00Z","event":"audit_finding","id":"combat.attack_combo_damage","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/GameLib/WeaponTrace.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/WeaponTrace.h","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstance.h","project/net_play.gd","project/fx/skill_fx.gd","audit/contracts/combat.attack-combo-damage.md"],"reason":"完成 WeaponTrace 静态核对:参考按武器骨骼矩阵/时间采样构建刀光顶点带,并有动态池、alpha/texture、reach scale、TurnOn/TurnOff/清理;当前战斗链没有等价的逐动作骨骼刀光资源与回收证据,合同保持 PARTIAL。"}
{"time":"2026-09-21T07:40:00Z","event":"audit_finding","id":"combat.flying_projectile","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/GameLib/FlyingData.h","../40250/Server Client TMP4/ClientVS22/source/GameLib/FlyingInstance.h","../40250/Server Client TMP4/ClientVS22/source/GameLib/FlyingObjectManager.h","../40250/Server Client TMP4/ClientVS22/source/GameLib/FlyTrace.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/FlyTrace.h","project/fly_object.gd","project/net_world.gd","audit/contracts/combat.flying-projectile.md"],"reason":"完成 GameLib flying-core 静态核对:参考 `.fly` 参数、目标/速度/剩余射程/已命中集合、index/type manager、attach effect 和 FlyTrace tail 均有独立生命周期;当前基础弹道通过但普通参数、动态 Actor 碰撞、去重和完整尾迹仍缺,合同保持 PARTIAL。"}
{"time":"2026-09-21T07:40:00Z","event":"audit_finding","id":"world.terrain_water_collision","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoor.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoorQuadtree.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoorIndexBuffer.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoorCharacterShadow.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/TerrainPatch.cpp","../40250/Server Client TMP4/ClientVS22/source/PRTerrainLib/Terrain.h","../40250/Server Client TMP4/ClientVS22/source/PRTerrainLib/TerrainType.h","../40250/Server Client TMP4/ClientVS22/source/PRTerrainLib/TextureSet.cpp","project/world/world_time.gd","extension/src/metin2_world.cpp","audit/contracts/world.terrain-water-collision.md"],"reason":"完成 GameLib/PRTerrainLib 地形核心静态核对:参考 MapOutdoor ray/water/environment、quadtree、patch hardware/software vertex、TextureSet 和角色 shadow render target 有独立生命周期;当前 Godot 高度/水面/terrain-splat 只有部分视觉与数据替代,patch/culling/shadow/卸载未统一,合同保持 PARTIAL。"}
{"time":"2026-09-21T07:40:00Z","event":"audit_finding","id":"world.map_load_transition","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/GameLib/MapBase.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/MapOutdoor.h","../40250/Server Client TMP4/ClientVS22/source/GameLib/MapManager.h","../40250/Server Client TMP4/ClientVS22/source/GameLib/MapType.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/MapUtil.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/AreaLoaderThread.h","../40250/Server Client TMP4/ClientVS22/source/GameLib/Property.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/PropertyLoader.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/PropertyManager.cpp","extension/src/metin2_world.cpp","project/game_scene.gd","audit/contracts/world.map-load-transition.md"],"reason":"完成 GameLib map/property 支持静态核对:参考 MapBase Leave/Enter、MapType/MapUtil 环境解析、AreaLoaderThread、Property CRC/register/clear 构成地图资源边界;当前方形 chunk/PropertyRegistry/延迟 queue_free 没有同一顺序和 generation,合同保持 PARTIAL。"}
{"time":"2026-09-21T07:40:00Z","event":"audit_finding","id":"world.dungeon_activity","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/GameLib/DungeonBlock.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/DungeonBlock.h","project/dungeon_state.gd","project/dungeon_result_test.gd","audit/contracts/world.dungeon-activity.md"],"reason":"完成 DungeonBlock 静态核对:参考多模型、deformable vertex buffer、bounding sphere、intersection、collision/height、Update/Render/Shadow/Destroy 是地图对象链;当前只覆盖副本目标/结果 helper,合同保持 PARTIAL。"}
{"time":"2026-09-21T07:40:00Z","event":"audit_finding","id":"resource.pack_locale_proto","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/EterPack/EterPack.h","../40250/Server Client TMP4/ClientVS22/source/EterPack/EterPackManager.h","../40250/Server Client TMP4/ClientVS22/source/EterPack/EterPackCursor.h","../40250/Server Client TMP4/ClientVS22/source/EterPack/EterPackPolicy_CSHybridCrypt.h","../40250/Server Client TMP4/ClientVS22/source/EterLocale/CodePageId.h","../40250/Server Client TMP4/ClientVS22/source/EterLocale/StringCodec.h","../40250/Server Client TMP4/ClientVS22/source/EterLocale/Arabic.h","../40250/Server Client TMP4/ClientVS22/source/EterLocale/Japanese.h","../40250/Server Client TMP4/ClientVS22/source/EterLocale/StringCodec_Vietnamese.h","project/locale.gd","extension/src/pack/eterpack.cpp","audit/contracts/resource.pack-locale-proto.md"],"reason":"完成 EterPack/EterLocale/GameLib 资源静态核对:参考 EPKD v2/index CRC/root-dir/search/cache/mapped cursor、HybridCrypt SDB 和 CP874/932/936/949/950/125x/UTF8、Arabic/Shift-JIS/Vietnamese 分支;当前自定义 pack 和 UTF-8 locale 不等价,合同保持 PARTIAL。"}
{"time":"2026-09-21T07:40:00Z","event":"audit_finding","id":"world.npc_drop_actor_spawn","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/GameLib/MonsterAreaInfo.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/Property.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/PropertyLoader.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/PropertyManager.cpp","extension/src/net/entity_store.cpp","project/net_world.gd","audit/contracts/world.npc-drop-actor-spawn.md"],"reason":"完成 GameLib MonsterAreaInfo/property 静态核对:参考保存刷怪区域边界、数量、随机位置、方向、group/VID/name 和清理默认值;当前主要依赖服务端 spawn packet,没有等价静态刷怪区域消费链,合同保持 PARTIAL。"}
{"time":"2026-09-21T08:00:00Z","event":"audit_finding","id":"network.packet_dispatch_protocol","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/EterLib/NetStream.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/NetStream.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/NetDatagram.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/NetDatagramReceiver.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/NetDatagramSender.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/NetDevice.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/NetPacketHeaderMap.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/NetAddress.cpp","extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_parser.cpp","audit/contracts/network.packet-dispatch.md"],"reason":"完成 EterLib transport-core 静态核对:参考 NetStream 的 connect/buffer/Peek/Recv/Send/sequence/security、UDP datagram、header map 和 NetDevice 清理;当前 classic 适配层未证明 partial read、sequence、UDP 辅助路径和断线清理全部闭环,合同保持 PARTIAL。"}
{"time":"2026-09-21T08:00:00Z","event":"audit_finding","id":"movement.click_collision","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpCollisionObject.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpCollisionObject.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/Ray.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/lineintersect_utils.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/lineintersect_utils.h","project/player_controller.gd","project/test_click_target_effect_parity.gd","audit/contracts/movement.click-collision.md"],"reason":"完成 EterLib picking-core 静态核对:参考支持 mesh/indexed triangle、bbox/cube、sphere/cylinder、固定 range ray 和线段最近点调整;当前 Godot ray/AABB/胶囊/地面采样仅为适配近似,合同保持 PARTIAL。"}
{"time":"2026-09-21T08:00:00Z","event":"audit_finding","id":"resource.pack_locale_proto","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/EterLib/Util.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/TargaResource.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/JpegFile.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpImage.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpImageTexture.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpSubImage.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpDIB.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/DibBar.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/BlockTexture.cpp","project/asset_root.gd","project/ui/ui_assets.gd","audit/contracts/resource.pack-locale-proto.md"],"reason":"完成 EterLib image/font resource 静态核对:参考 Util 从 EterPack 读文本并按 code page 选字体,TGA/JPEG/DIB/分块纹理有独立 load/lock/clear;当前 ImageTexture/atlas/PCK 路径没有同一 pack、纹理恢复和失败清理链,合同保持 PARTIAL。"}
{"time":"2026-09-21T08:00:00Z","event":"audit_finding","id":"lifecycle.platform_release","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpDetector.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpBase.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/StateManager.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpVertexBuffer.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/GrpIndexBuffer.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/Pool.h","../40250/Server Client TMP4/ClientVS22/source/EterLib/ReferenceObject.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/Thread.cpp","../40250/Server Client TMP4/ClientVS22/source/EterLib/Event.h","project/app_lifecycle.gd","project/client_main.gd","audit/contracts/lifecycle.platform-release.md"],"reason":"完成 EterLib graphics/runtime utility 静态核对:参考 adapter/capability、backbuffer/camera、D3D state restore、buffer/shader/light、pool/ref/thread/event cleanup;当前 Godot 下沉引擎且没有 Windows lost/reset、池容量、引用自毁和线程 shutdown oracle,合同保持 PARTIAL。"}
{"time":"2026-09-21T08:20:00Z","event":"audit_finding","id":"lifecycle.bootstrap_phase_host","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/AbstractApplication.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/CheckLatestFiles.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/ProcessCRC.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/ProcessScanner.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/HackShield.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/NProtectGameGuard.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonApplicationModule.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonSystem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonExceptionSender.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/UserInterface.cpp","project/client_main.gd","project/app_flow.gd","project/app_lifecycle.gd","audit/contracts/lifecycle.bootstrap-phase-host.md"],"reason":"完成 UserInterface application/security 静态核对:参考 AbstractApplication/IME host、PythonApplication module、媒体/网页/配置、CRC/进程扫描、安全组件和异常上报链;当前 AppFlow 仅覆盖基础 Godot 生命周期,缺 Windows 安全/完整性/媒体/关闭/配置 host 等价实现,合同保持 PARTIAL。"}
{"time":"2026-09-21T08:20:00Z","event":"audit_finding","id":"lifecycle.platform_release","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonSystem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonSystemModule.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonApplicationLogo.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/MovieMan.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/ProcessCRC.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/ProcessScanner.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonExceptionSender.cpp","project/app_lifecycle.gd","project/system_options.gd","audit/contracts/lifecycle.platform-release.md"],"reason":"完成 UserInterface platform-host 静态核对:参考 D3D display/config、DirectShow/DirectDraw logo/movie、CRC/process scan/exception/security 发布门禁;当前 Godot 配置和媒体路径无 Windows surface/安全组件/完整性验证,合同保持 PARTIAL。"}
{"time":"2026-09-21T08:45:00Z","event":"audit_finding","id":"network.character_select.create_delete","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/AbstractCharacterManager.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonCharacterManager.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonCharacterManagerModule.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonCharacterModule.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/AccountConnector.h","project/char_select_screen.gd","project/net_play.gd","project/net_world.gd","audit/contracts/network.character-select.md"],"reason":"完成 UserInterface character-manager 静态核对:参考 VID 实例表、main/selected/fade/dead list、device/point effect、RaceData weighted motion registration 和创建/删除/选择/装备/动作入口;当前角色选择与 NetWorld 只有部分生命周期镜像,合同保持 PARTIAL。"}
{"time":"2026-09-21T08:45:00Z","event":"audit_finding","id":"movement.keyboard_motion","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseEvent.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseTransform.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerEventHandler.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/AbstractPlayer.h","project/player_controller.gd","project/net_play.gd","audit/contracts/movement.keyboard-motion.md"],"reason":"完成 UserInterface actor-transform/event 静态核对:参考 InstanceBase 与 ActorInstance handler 对齐位置/rotation/LookAt/移动/攻击/技能/受击/warp,并在 bow event 帧产生 fly target/shoot;当前移动信号与远端消费顺序、锁门恢复和模型根运动仍未完全一致,合同保持 PARTIAL。"}
{"time":"2026-09-21T08:45:00Z","event":"audit_finding","id":"world.entity_spawn_state_sync","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/NetworkActorManager.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/AbstractCharacterManager.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonCharacterManager.h","extension/src/net/entity_store.cpp","project/net_world.gd","audit/contracts/world.entity-spawn-state-sync.md"],"reason":"完成 NetworkActorManager/character manager 静态核对:参考以 server time、目标位置/持续时间、owner/victim、affect flags 和统一 fade/delete/update 驱动实例;当前 EntityStore/NetWorld 仅做快照插值,VID 复用、主角色切换和远端删除语义仍有已知失败,合同保持 PARTIAL。"}
{"time":"2026-09-21T08:45:00Z","event":"audit_finding","id":"world.npc_drop_actor_spawn","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNonPlayer.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNonPlayerModule.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonCharacterModule.cpp","extension/src/proto/proto.cpp","extension/src/net/entity_store.cpp","project/net_world.gd","audit/contracts/world.npc-drop-actor-spawn.md"],"reason":"完成 UserInterface NPC 数据入口静态核对:参考 MMPT LoadNonPlayerData、vnum/name/type/event/color、VID event lookup 与等级匹配,并将 event type 传给角色行为;当前 proto/EntityStore 只闭合基础 spawnunknown/fallback/event/color/筛选链仍不完整,合同保持 PARTIAL。"}
{"time":"2026-09-21T08:45:00Z","event":"audit_finding","id":"world.map_load_transition","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonBackground.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonBackgroundModule.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/CameraProcedure.cpp","project/game_scene.gd","extension/src/metin2_world.cpp","audit/contracts/world.map-load-transition.md"],"reason":"完成 UserInterface Background/CameraProcedure 静态核对:参考暴露地图/环境/height/picking/shadow/splat/view distance/guild area/target effect/Warp,并用 terrain-only ray 做多方向相机碰撞;当前 world 有主路径但没有同一 bridge 的环境索引、shadow/splat/view-distance 和 special cleanup,合同保持 PARTIAL。"}
{"time":"2026-09-21T08:45:00Z","event":"audit_finding","id":"resource.pack_locale_proto","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_BR.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_CA.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_EU.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_EU2.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_GB.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_HK.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_JP.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_KO.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_KO_DEV.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_NEWCIBN.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_SG.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_VI.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_dev.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/GameType.cpp","project/locale.gd","project/ui/ui_assets.gd","audit/contracts/resource.pack-locale-proto.md"],"reason":"完成 UserInterface locale/font bridge 静态核对:参考编译期 locale/codepage/font/feature 变体以及 CResourceManager 默认字体和 guild symbol 路径;当前运行时 UTF-8 lang/text table 没有同一来源与字体重载语义,合同保持 PARTIAL。"}
{"time":"2026-09-21T09:15:00Z","event":"audit_finding","id":"social.party_guild_messenger","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/GuildMarkDownloader.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/GuildMarkUploader.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/MarkImage.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/MarkImage.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/MarkManager.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonGuild.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonMessenger.h","extension/src/net/classic/classic_mark_client.cpp","project/guild_mark_uploader_system.gd","project/messenger_system.gd","audit/contracts/social.party-guild-messenger.md"],"reason":"完成 UserInterface 会徽与社交状态静态核对:参考端是独立 mark stream、index/CRC/LZO block、guild mark 持久映射、guild/messenger 回包状态;当前端虽有 native mark client,仍存在本地缓存/字典旁路及真实分片失败、权限、重连和角色刷新未验证,合同保持 PARTIAL。"}
{"time":"2026-09-21T09:15:00Z","event":"audit_finding","id":"social.chat_text_tail","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/InsultChecker.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InsultChecker.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonChatModule.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonTextTailModule.cpp","project/chat_system.gd","project/text_tail.gd","audit/contracts/social.chat-text-tail.md"],"reason":"完成 UserInterface 聊天/尾标静态核对:参考端含 locale 多字节禁词过滤、chat set/whisper/item hyperlink、尾标更新/投影/pick/排列;当前端局部 helper 未形成同一生产链,合同保持 PARTIAL。"}
{"time":"2026-09-21T09:15:00Z","event":"audit_finding","id":"quest.quest_event_navigation","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonEventManagerMoudle.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonGameEventManagerModule.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonQuest.h","project/quest_dialog.gd","project/quest_hud.gd","project/atlas_ui.gd","audit/contracts/quest.quest-event-navigation.md"],"reason":"完成 UserInterface 任务事件桥静态核对:参考端拥有 event-set 注册/handler/answer/位置/等待/跳过、逐帧 game event 和 quest instance clock/counter/icon;当前端任务生命周期、wire button、电影消费和 Atlas 信号仍有差异,合同保持 PARTIAL。"}
{"time":"2026-09-21T09:15:00Z","event":"audit_finding","id":"social.exchange_safebox","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonExchange.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonExchangeModule.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonSafeBox.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonShop.h","project/exchange_ui.gd","project/safebox_ui.gd","project/shop_ui.gd","audit/contracts/social.exchange-safebox.md"],"reason":"完成 UserInterface 交易/仓库/商城静态核对:参考端分离双方交易字段、socket/attribute、safebox/mall slot-money、普通/私有商店 tab-stock;当前端仍有 optimistic/helper authority 与真实回包回滚、动作门控和重连分支缺口,合同保持 PARTIAL。"}
{"time":"2026-09-21T09:15:00Z","event":"audit_finding","id":"ui.input_camera_mobile","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonIME.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonIMEModule.cpp","project/ui/chat_input.gd","project/input_router.gd","audit/contracts/ui.input-camera-mobile.md"],"reason":"完成 UserInterface IME bridge 静态核对:参考端覆盖光标编辑、WM_CHAR、候选/reading、codepage、输入模式和焦点清理;当前端 LineEdit 只证明基本 UTF-8 输入,合同保持 PARTIAL。"}
{"time":"2026-09-21T09:15:00Z","event":"audit_finding","id":"ui.hud_target_minimap_status","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonMiniMapModule.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonTextTailModule.cpp","project/minimap.gd","project/text_tail.gd","audit/contracts/ui.hud-target-minimap-status.md"],"reason":"完成 UserInterface minimap/text-tail bridge 静态核对:参考端包含 atlas/waypoint/guild-area/pick 和统一尾标更新/投影/排列;当前生产 owner、删除/重置、投影失败和字体资源链仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T09:15:00Z","event":"audit_finding","id":"network.packet_dispatch_protocol","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkDatagram.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkDatagram.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkDatagramModule.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStream.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseOffline.cpp","extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_parser.cpp","audit/contracts/network.packet-dispatch.md"],"reason":"完成 UserInterface packet bridge 静态核对:参考端分离 datagram sender/header 生命周期、全量 stream 请求/phase 入口和 offline 清理;当前 classic 适配层未证明所有门控、partial read、未知包和副作用顺序等价,合同保持 PARTIAL。"}
{"time":"2026-09-21T09:15:00Z","event":"audit_finding","id":"network.reconnect_warp","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkDatagram.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkDatagramModule.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStream.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseOffline.cpp","extension/src/net/classic/classic_session.cpp","project/net_play.gd","project/app_flow.gd","audit/contracts/network.reconnect-warp.md"],"reason":"完成 UserInterface warp/offline bridge 静态核对:参考端要求 phase、sender、旧包和 stream 清理顺序一致;当前 connect_warp/world_reset 有主路径但 sender 注销、旧包隔离和 selected/direct-enter 状态仍缺逐分支证据,合同保持 PARTIAL。"}
{"time":"2026-09-21T09:15:00Z","event":"audit_finding","id":"network.error_timeout_server_state","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/ServerStateChecker.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/ServerStateCheckerModule.cpp","project/net/channel_status.gd","project/channel_status_test.gd","audit/contracts/network.error-timeout-server-state.md"],"reason":"完成 ServerStateChecker 静态核对:参考端维护独立 probe stream、channel 地址/端口、Request/Update/window 回调;当前端 smoke test 通过但并发、超时、远端关闭、窗口销毁和 login 竞态清理未证明等价,合同保持 PARTIAL。"}
{"time":"2026-09-21T09:15:00Z","event":"audit_finding","id":"skill.player_ui_cooldown","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonSkill.h","project/skill_table.gd","project/quickbar.gd","project/skill_test.gd","audit/contracts/skill.player-ui-cooldown.md"],"reason":"完成 PythonSkill 数据桥静态核对:参考技能表/描述提供范围、限制、状态公式、cooldown/SP、loop/target/duration/motion/grade 等输入;当前 casting speed、资源公式、grade/motion 和拒绝后的 cooldown rollback 未统一,合同保持 PARTIAL。"}
{"time":"2026-09-21T09:15:00Z","event":"audit_finding","id":"skill.cast_effect_timing","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonSkill.h","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceEvent.cpp","project/net_world.gd","project/ui/player_view.gd","project/fx/skill_fx.gd","audit/contracts/skill.cast-effect-timing.md"],"reason":"完成 PythonSkill 与 GameLib event 输入桥静态核对:参考技能数据驱动动作循环、移动技能、grade、飞行/命中/特殊攻击事件;当前资源字段到正式远端动作和特效 cleanup 的链路仍未证明等价,合同保持 PARTIAL。"}
{"time":"2026-09-21T09:15:00Z","event":"audit_finding","id":"resource.pack_locale_proto","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_BR.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_CA.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_EU.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_EU2.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_GB.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_HK.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_JP.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_KO.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_KO_DEV.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_NEWCIBN.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_SG.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_VI.h","../40250/Server Client TMP4/ClientVS22/source/UserInterface/Locale_inc_dev.h","project/locale.gd","project/ui/ui_assets.gd","audit/contracts/resource.pack-locale-proto.md"],"reason":"登记完成 UserInterface Locale/locale-variant 全量 active source 静态核对:参考编译期 locale/codepage/font/feature 变体和默认字体/guild symbol 入口;当前运行时 UTF-8 locale 没有同一来源与字体重载语义,合同保持 PARTIAL。"}
{"time":"2026-09-20T18:19:19Z","event":"audit_finding","id":"item.inventory_equipment_state","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp","extension/src/net/m2_client.cpp","project/ui/inventory_ui.gd","audit/contracts/item.inventory-equipment-state.md"],"reason":"下一轮物品/装备入口审计:native M2Client 仍缺 40250 的 __CanActMainInstance、装备交易/商店/攻击中门、物品音效、Set2 highlight 与 Update 中间刷新语义;局部 native/UI 回归通过,合同保持 PARTIAL。"}
{"time":"2026-09-20T18:19:19Z","event":"audit_finding","id":"ui.equipment.tooltip","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/EterPythonLib/PythonSlotWindow.cpp","../40250/Server Client TMP4/Client/Eternexus/root/uitooltip.py","project/ui/inventory_ui.gd","project/ui/shop_ui.gd","project/ui/view_equipment_ui.gd","project/ui/ui_manager.gd","audit/contracts/ui.equipment-tooltip.md"],"reason":"下一轮 tooltip 审计:查看装备路径复用单个 ItemTooltipView 且局部测试通过,但 InventoryUI/ShopUI 仍同时设置原生 tooltip_text 和共享属性面板,存在全局双面板路径;窗口边界与清理证据不足,合同保持 PARTIAL。"}
{"time":"2026-09-20T18:19:19Z","event":"audit_finding","id":"item.refine_socket_costume","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerModule.cpp","extension/src/net/m2_client.cpp","project/ui/refine_ui.gd","project/item_attr_system.gd","project/jewelry_socket_system.gd","project/costume_system.gd","audit/contracts/item.refine-socket-costume.md"],"reason":"下一轮强化/镶嵌/时装入口审计:M2Client::refine 拒绝 40250 取消 sentinel(255,255);旧/新版 refine parser 已存在,但本地属性/socket/costume 字典旁路仍未接入服务器权威 item/affect/actor 回包,合同保持 PARTIAL。"}
{"time":"2026-09-20T18:31:56Z","event":"implementation_fix_round","result":"PARTIAL","ids":["item.refine_socket_costume","ui.equipment.tooltip","combat.death.exp_drop"],"files":["extension/src/net/net_bounds.h","extension/src/net/m2_client.cpp","extension/src/net/entity_store.cpp","project/player_controller.gd","project/net_play.gd","project/ui/inventory_ui.gd","project/ui/shop_ui.gd"],"tests":["extension/tests/net_bounds_test.cpp","extension/tests/net_entity_test.cpp","project/inventory_ui_test.gd","project/view_equipment_ui_test.gd","project/test_npc_shop_flow.gd","project/test_combat_death_pickup_entry_parity.gd","project/netplay_test.gd"],"reason":"按 40250 调用链修复强化取消 sentinel 入口、物品属性单面板 owner、主角死亡移动/自动动作门和正 HP 复活边沿;回归测试通过,完整服务器权威链和剩余合同仍保持 PARTIAL。"}
{"time":"2026-09-20T18:31:56Z","event":"audit_finding","id":"item.inventory_equipment_state","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameActor.cpp","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_parser.cpp","extension/src/net/classic/classic_session.cpp","extension/src/net/entity_store.cpp","audit/contracts/item.inventory-equipment-state.md"],"reason":"下一轮物品/装备状态核对确认:40250 的 Set2 highlight 与 Update 中间刷新时序在当前端没有等价事件;native 物品操作只做阶段/范围校验,未统一复刻 CanActMainInstance、交易/商店/攻击中门和物品音效,合同继续 PARTIAL。"}
{"time":"2026-09-20T18:46:35Z","event":"implementation_fix_round","result":"PARTIAL","ids":["item.inventory_equipment_state"],"files":["extension/src/net/item_action_rules.h","extension/src/net/m2_client.cpp","extension/src/net/m2_client.h","extension/src/net/entity_store.h","extension/src/net/entity_store.cpp","extension/src/net/classic/classic_parser.cpp","project/ui/inventory_ui.gd","project/inventory_ui_test.gd","extension/tests/net_bounds_test.cpp","extension/tests/net_entity_test.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/item.inventory-equipment-state.md"],"tests":["cmake --build build","ctest --test-dir build --output-on-failure","godot --headless --path project --script inventory_ui_test.gd"],"reason":"按 40250 物品发送入口补齐 native 主角行动门和 dedicated equipment window 的交易/私店/攻击中门;保留并消费 Set2 highlight,确保高亮信号先于 inventory_changedUpdate 双刷新、ItemManager 装备分类、音效/sequence、未知 vnum 和断线回滚仍保持 PARTIAL。"}
{"time":"2026-09-20T18:46:35Z","event":"implementation_fix_round","result":"PARTIAL","ids":["combat.attack_combo_damage"],"files":["project/net_play.gd","project/combat_fx_test.gd","audit/contracts/combat.attack-combo-damage.md"],"tests":["godot --headless --path project --script combat_fx_test.gd","godot --headless --path project --script combat_parity_test.gd","godot --headless --path project --script gamescene_test.gd"],"reason":"按 ActorInstance::ComboAttack → __SetMotion → PythonPlayerEventHandler::OnAttack 的 40250 顺序,改为先绑定动作/命中窗口和弓箭目标,再发送 FUNC_COMBO;补充跨对象顺序回归断言。WeaponTrace、真实服务器命中闭环和缺资源 fallback 仍保持 PARTIAL。"}
{"time":"2026-09-20T18:46:35Z","event":"audit_finding","id":"movement.keyboard_motion","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInputKeyboard.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseMovement.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceMotion.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerEventHandler.cpp","project/player_controller.gd","project/net_play.gd","project/keyboard_motion_timeline_test.gd","project/test_wasd_steering_parity.gd","project/test_no_auto_move_regression.gd","audit/contracts/movement.keyboard-motion.md"],"reason":"本轮输入回归全部通过,但静态对比确认固定 300 像素目标+根运动仍由连续速度预测替代,动作资源事件与移动网络事件来源不同,受击/情绪/移动技能解锁恢复和相机旋转副作用未闭合;合同保持 PARTIAL。"}
{"time":"2026-09-20T19:03:44Z","event":"implementation_fix_round","result":"PARTIAL","ids":["movement.keyboard_motion","item.inventory_equipment_state"],"files":["project/player_controller.gd","project/keyboard_motion_timeline_test.gd","extension/src/net/entity_store.h","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","project/ui/inventory_ui.gd","extension/tests/net_entity_test.cpp","audit/contracts/movement.keyboard-motion.md","audit/contracts/item.inventory-equipment-state.md"],"tests":["godot --headless --path project --script keyboard_motion_timeline_test.gd","godot --headless --path project --script player_move_test.gd","godot --headless --path project --script test_wasd_steering_parity.gd","godot --headless --path project --script test_no_auto_move_regression.gd","cmake --build build -j2","ctest --test-dir build --output-on-failure","godot --headless --path project --script inventory_ui_test.gd","git diff --check"],"reason":"按 40250 NEW_MoveToDirection 固定 300 像素目标修复键盘移动目标消费;按 RecvItemUpdatePacket 的 count 刷新→socket/attribute→末尾刷新顺序,新增 InvChange 快照和 inventory_state_changed 适配。实现和测试均通过,但根运动/资源事件、全部旧监听者、ItemManager 分类、音效/sequence、回滚与换图边界仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-20T19:03:44Z","event":"audit_finding","id":"combat.death.exp_drop","result":"PARTIAL","files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseBattle.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstance.cpp","../40250/Server Client TMP4/ClientVS22/source/GameLib/FlyingData.cpp","extension/src/net/classic/classic_parser.cpp","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","project/net_play.gd","project/net_world.gd","project/player_controller.gd","project/fly_object.gd","project/ui/ground_items.gd","audit/contracts/combat.death-exp-drop.md"],"tests":["godot --headless --path project --script test_combat_death_pickup_entry_parity.gd","godot --headless --path project --script mob_death_drop_test.gd","godot --headless --path project --script combat_parity_test.gd","godot --headless --path project --script playable_combat_test.gd","godot --headless --path project --script gamescene_test.gd","build/extension/net_state_queue_test","build/extension/net_entity_test"],"reason":"主角死亡后的输入/自动攻击清理、正 HP 复活边沿、POINT_EXP.amount 单次消费和基础 FLY_EXP/掉落回归通过;仍缺 40250 ShowPointEffect 与 POINT_GOLD.amount 事件、真实 .fly/索引资源与包序、owner/重连/跨图异常清理,合同保持 PARTIAL。"}
{"time":"2026-09-20T19:17:28Z","event":"implementation_fix_round","result":"PARTIAL","ids":["combat.death.exp_drop"],"files":["extension/src/net/wire.h","extension/src/net/entity_store.h","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","extension/tests/net_entity_test.cpp","project/net_play.gd","project/net_world.gd","project/ui/skill_ui.gd","project/netplay_test.gd","audit/contracts/combat.death-exp-drop.md","audit/manifest.json"],"tests":["cmake --build build -j2","build/extension/net_entity_test","godot --headless --path project --script netplay_test.gd","godot --headless --path project --script test_levelup_combat_parity.gd","godot --headless --path project --script combat_fx_test.gd","godot --headless --path project --script netbridge_test.gd","godot --headless --path project --script test_combat_death_pickup_entry_parity.gd","godot --headless --path project --script test_exp_fly_parity.gd","godot --headless --path project --script test_taskbar_quickslot_parity.gd","godot --headless --path project --script skill_test.gd","godot --headless --path project --script char_status_ui_test.gd"],"reason":"按 40250 RecvPointChange/ShowPointEffect 统一 classic 与 m2dev 点变更入口,新增 point_changed 顺序事件、等级/技能 MSE 目标特效、金币 amount 反馈、能量归零清理及属性/技能刷新分支;新增原生/GDScript 回归并修复无独立本地节点时 NetWorld 错误跳过主实体。真实 effect manager 生命周期、完整金币浮字/窗口旁路、服务端包序和跨图异常清理仍保持 PARTIAL。"}
{"time":"2026-09-21T09:30:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow"],"files":["project/ui/loading_screen.gd","project/ui/char_select_screen.gd","audit/contracts/network.login.phase-flow.md","audit/manifest.json"],"tests":["godot --headless --path project --script p10_test.gd","godot --headless --path project --script app_flow_lifecycle_test.gd","git diff --check"],"reason":"按 40250 RecvPhasePacket -> SetLoadingPhase/SetGamePhase 修复 LoadingScreen 的阶段属主:仅 loading 显示全屏遮罩,game/login/select 均释放遮罩和输入拦截;选人确认在 tree-owned 节点离树时取消,在无 SceneTree 的 headless/reconnect harness 中直接发出一次 select_requested,修复选人吞包和重连回放失败。PHASE_CLOSE、失败重试清理、deadline、密码生命周期、可选安全分支和真实服务端包序仍保持 PARTIAL。"}
{"time":"2026-09-21T09:50:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.character_select.create_delete"],"files":["extension/src/net/classic/classic_parser.h","extension/src/net/classic/classic_parser.cpp","extension/src/net/classic/classic_session.h","extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.character-select.md","audit/manifest.json"],"tests":["cmake --build build -j2","ctest --test-dir build --output-on-failure","godot --headless --path project --script char_create_delete_test.gd","godot --headless --path project --script test_intro_select_parity.gd","godot --headless --path project --script p10_test.gd","godot --headless --path project --script app_flow_lifecycle_test.gd","git diff --check"],"reason":"按 40250 固定槽数组和 phase 分支修复 legacy LOGIN_SUCCESS3 的第 4 空槽、创建成功越界事件、未知改名 PID 的错误码 100、帝国本地写入时点和 DirectEnter PHASE_SELECT 的额外 CG_PLAYER_SELECTnative session、全量 23 项 ctest、角色 UI、选人和生命周期回归均通过。locale codepage、异常双窗口回调、重复进入/中断清理、实例管理器生命周期和真实服务端包序仍保持 PARTIAL。"}
{"time":"2026-09-21T10:15:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.packet_dispatch_protocol"],"files":["extension/src/net/classic/wire_classic.h","extension/src/net/classic/classic_stream.cpp","extension/tests/net_classic_wire_test.cpp","extension/tests/net_classic_stream_test.cpp","audit/contracts/network.packet-dispatch.md","audit/manifest.json"],"tests":["cmake --build build -j2 --target net_classic_stream_test net_classic_wire_test net_classic_session_test","build/extension/net_classic_wire_test","build/extension/net_classic_stream_test","build/extension/net_classic_session_test","python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_packet_registry.py --strict","ctest --test-dir build --output-on-failure","git diff --check"],"reason":"按 40250 CMainPacketHeaderMap 的 STATIC GC_WHISPER 与 RecvWhisperPacket 两段式读取修复当前 framing:固定头先按静态尺寸等待,再按 wSize 等待文本尾,parser body 去掉 header/wSize,连续后续包边界保持正确;registry 额外差异收敛为已登记的 SYMBOL_DATA 兼容分支。四阶段 allowlist、burst tick、完整 117 项机器映射和 QUEST_INFO/GUILD 特殊声明尺寸仍保持 PARTIAL。"}
{"time":"2026-09-21T10:45:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.reconnect_warp"],"files":["extension/src/net/classic/classic_stream.h","extension/src/net/classic/classic_stream.cpp","extension/src/net/classic/classic_session.h","extension/src/net/m2_client.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.reconnect-warp.md","audit/manifest.json"],"tests":["cmake --build build -j2 --target net_classic_session_test net_classic_stream_test mtgodot","build/extension/net_classic_session_test","build/extension/net_classic_stream_test","ctest --test-dir build --output-on-failure","godot --headless --path project --script p10_test.gd","godot --headless --path project --script app_flow_lifecycle_test.gd","godot --headless --path project --script gamescene_test.gd","godot --headless --path project --script p9_test.gd","git diff --check"],"reason":"按 40250 CNetworkStream::Connect(limitSec=3) 增加 ClassicStream 3000ms 非阻塞连接 deadlinegeneric reconnect 在已有 login key/selected slot 时改为同一 ClassicSession 的 Clear->Connect,保留 selected slot/login key/DirectEnter,并对连接中重复重试做幂等保护;native 23 项 ctest 与 P10/P9 回归通过。真实阻塞超时、旧新 socket 竞态、同服/跨服 burst 包序和清理 owner 时序仍保持 PARTIAL。"}
{"time":"2026-09-21T11:15:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.security_encoding"],"files":["extension/src/net/classic/classic_stream.h","extension/src/net/classic/classic_stream.cpp","extension/tests/net_classic_stream_test.cpp",".agents/skills/metin2-40250-parity-audit/scripts/audit_sequence_table.py","audit/contracts/network.security-encoding.md","audit/manifest.json"],"tests":["cmake --build build -j2 --target net_classic_stream_test net_classic_session_test mtgodot","build/extension/net_classic_stream_test","build/extension/net_classic_session_test","python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_sequence_table.py","git diff --check"],"reason":"按 40250 RecvHandshakePacket/RecvHandshakeOKPacket 修复 Select/Game 后续 handshake 的 pending server clockCG_TIME_SYNC 发送后不提前切换活动时钟,收到 HANDSHAKE_OK 才按 changeClientTime elapsed 提交;断开清理 pending 状态。新增 sequence table 逐字节审计,当前 32768 项与 40250 SHA-256 完全一致。全局 ELTimer/CTimer owner、legacy TEA、HybridCrypt/Panama/HS-XTrap、Windows codepage、flush 加密时点和真实 server fixture 仍保持 PARTIAL。"}
{"time":"2026-09-21T11:45:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["movement.keyboard.motion"],"files":["project/player_controller.gd","project/keyboard_motion_timeline_test.gd","project/player_motion_test.gd","audit/contracts/movement.keyboard-motion.md","audit/manifest.json"],"tests":["godot --headless --path project --script keyboard_motion_timeline_test.gd","godot --headless --path project --script test_wasd_steering_parity.gd","godot --headless --path project --script test_no_auto_move_regression.gd","godot --headless --path project --script player_motion_test.gd","git diff --check"],"reason":"按 40250 CPythonPlayer::Update 在 m_isDirKey 下每帧重试 NEW_SetMultiDirKeyState 的语义,保留锁定/受击同步/移动技能期间的 held WASD 状态,清除旧固定目标并在解锁/技能结束的首个更新恢复 300cm 目标;W/S、翻转、无自动移动和真实模型动作回归均退出码 0。player_motion_test 同步清理 native model/animation 节点并清空测试缓存,消除 ObjectDB 泄漏与 exit 139。真实 .msa 根运动、动作事件源、相机副作用、私店/同步/受击/情绪/传送边界和完整网络时间线仍保持 PARTIAL。"}
{"time":"2026-09-21T12:30:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["skill.cast.effect_timing"],"files":["project/ui/skill_table.gd","project/ui/quickbar.gd","project/game_scene.gd","project/net_world.gd","project/ui/player_view.gd","extension/src/net/entity_store.h","extension/src/net/entity_store.cpp","extension/src/net/m2_client.h","extension/src/net/m2_client.cpp","extension/tests/net_state_queue_test.cpp","project/test_skill_state_arg_parity.gd","audit/contracts/skill.cast-effect-timing.md","audit/manifest.json"],"tests":["godot --headless --path project --script skill_test.gd","godot --headless --path project --script test_skill_state_arg_parity.gd","godot --headless --path project --script test_skill_ground_fix.gd","godot --headless --path project --script playable_combat_test.gd","godot --headless --path project --script gamescene_test.gd","godot --headless --path project --script p10_test.gd","godot --headless --path project --script player_motion_test.gd","godot --headless --path project --script combat_fx_test.gd","godot --headless --path project --script skill_fx_test.gd","godot --headless --path project --script effect_playback_test.gd","build/extension/net_state_queue_test","build/extension/net_entity_test","ctest --test-dir build --output-on-failure","git diff --check"],"reason":"按 40250 CActorInstance::__OnUseSkill 的 uArg = uLoopCount | (isMovingSkill << 4) 修复技能动作参数丢失:.msk MotionLoopCountFormula 统一计算并由快捷栏/本地主角上行,EntityStore 在近距立即施法与远距到达后均保留 func_argNetWorld 解包后传递到 PlayerView。技能表、网络状态队列、场景与动作回归通过;SetMotionLoopCount 真实片段循环、远端 grade 来源、挂点/颜色/混合、完整 MSA/MSE/服务端结果时间线仍保持 PARTIAL。"}
{"time":"2026-09-21T13:00:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["item.inventory_equipment_state"],"files":["extension/src/net/item_action_rules.h","extension/src/net/m2_client.h","extension/src/net/m2_client.cpp","project/game_scene.gd","extension/tests/net_bounds_test.cpp","audit/contracts/item.inventory-equipment-state.md","audit/manifest.json"],"tests":["cmake --build build -j2 --target net_bounds_test mtgodot","build/extension/net_bounds_test","ctest --test-dir build --output-on-failure","godot --headless --path project --script inventory_ui_test.gd","godot --headless --path project --script equip_model_test.gd","godot --headless --path project --script netbridge_test.gd","git diff --check"],"reason":"按 40250 TItemPos::IsEquipCell + CPythonPlayer::IsEquipItemInSlot + CItemData::IsEquipment 修复 native 装备性判断:M2Client 复用 GameScene 已加载的 item_proto,装备操作只对装备区内且 type 为 WEAPON/ARMOR 的物品触发交易/商店/攻击中门;空槽、时装、戒指、腰带不再仅因窗口编号误触发,缺少 proto 的过渡期保留 fail-closed 限制。未知 vnum store 校验、物品音效/sequence、旧刷新监听者中间状态、拒绝回滚和换图重建仍保持 PARTIAL。"}
{"time":"2026-09-21T13:20:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["item.inventory_equipment_state"],"files":["extension/src/net/entity_store.h","extension/src/net/entity_store.cpp","extension/src/net/m2_client.h","extension/src/net/m2_client.cpp","extension/tests/net_entity_test.cpp","audit/contracts/item.inventory-equipment-state.md","audit/manifest.json"],"tests":["cmake --build build -j2 --target net_entity_test net_bounds_test mtgodot","build/extension/net_entity_test","build/extension/net_bounds_test","ctest --test-dir build --output-on-failure","godot --headless --path project --script inventory_ui_test.gd","godot --headless --path project --script equip_model_test.gd","godot --headless --path project --script netbridge_test.gd","git diff --check"],"reason":"按 40250 CPythonPlayer::SetItemData 的 ItemManager 资源校验修复未知 vnum 分支:EntityStore 支持可选 validator,未知 Set 保持原槽位且不发刷新/高亮;M2Client 在共享 item_proto 就绪后绑定 active world,并清理 proto 加载前进入 store 的非法物品,换图/重连新 world 重新绑定。未知 vnum、晚绑定清理与现有空槽 Update 回归通过;音效/sequence、拒绝回滚和换图乱序矩阵仍保持 PARTIAL。"}
{"time":"2026-09-21T13:45:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["item.consumable_action"],"files":["project/item_split_system.gd","project/ui/shop_ui.gd","project/test_item_split_parity.gd","audit/contracts/item.consumable-action.md","audit/manifest.json"],"tests":["godot --headless --path project --script test_item_split_parity.gd","godot --headless --path project --script complex_item_drop_test.gd","godot --headless --path project --script shop_rules_test.gd","git diff --check"],"reason":"按 40250 RequestUseLocalQuickSlot/SendItemMovePacket/SendShopSellPacket 的 request→server→GC 确认语义,移除 ItemSplitSystem 的本地拆分和快捷出售权威旁路:拆分改发 CG_ITEM_MOVE,出售改发 CG_SHOP SELL2,二者都在服务器确认前保持本地槽位和金币不变;ShopUI 购买模式拒绝拖入出售目标。20/20 拆分回归、复杂拖放回归和商店规则回归通过;快捷栏回滚、真实消耗品反馈包序、音效/sequence 和断线清理仍保持 PARTIAL。"}
{"time":"2026-09-21T14:15:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["item.consumable_action"],"files":["project/ui/quickbar.gd","project/test_skill_inventory_parity.gd","project/skill_test.gd","project/mobile_gesture_test.gd","project/test_skill_ground_fix.gd","project/test_taskbar_quickslot_parity.gd","audit/contracts/item.consumable-action.md","audit/manifest.json"],"tests":["godot --headless --path project --script test_skill_inventory_parity.gd","godot --headless --path project --script skill_test.gd","godot --headless --path project --script mobile_gesture_test.gd","godot --headless --path project --script test_taskbar_quickslot_parity.gd","godot --headless --path project --script test_skill_ground_fix.gd","git diff --check"],"reason":"按 40250 CPythonPlayer 的 request→GC 状态链修复 Quickbar.assign/_clear/_swap:在线请求成功不再乐观修改 _state,必须等待 GC_QUICKSLOT_* 驱动 quickslots_changed/restore_from_serverSetQuickPage 按 QUICKSLOT_MAX_LINE=4 取模。测试夹具改为显式模拟 GC 确认,新增延迟确认断言;快捷栏增删交换时序和页面环绕回归通过。快捷栏使用统一入口、真实拒绝/乱序/断线 fixture、消耗品反馈包序、音效/sequence 和生命周期清理仍保持 PARTIAL。"}
{"time":"2026-09-21T14:45:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["skill.player_ui_cooldown"],"files":["project/player_skill.gd","project/net_play.gd","project/ui/quickbar.gd","project/player_skill_test.gd","project/skill_test.gd","extension/src/net/wire.h","extension/src/net/m2_client.cpp","audit/contracts/skill.player-ui-cooldown.md","audit/manifest.json"],"tests":["cmake --build build -j2 --target net_bounds_test net_entity_test mtgodot","godot --headless --path project --script player_skill_test.gd","godot --headless --path project --script skill_test.gd","godot --headless --path project --script test_skill_inventory_parity.gd","godot --headless --path project --script playable_combat_test.gd","godot --headless --path project --script netplay_test.gd","git diff --check"],"reason":"按 40250 CInstanceBase::CanUseSkill 和 CPythonPlayer::__RunCoolTime 修复技能动作门与冷却:PlayerSkill 新增变身、礼服、矿镐、坐骑动作、图形动作五类 gate,NetPlay 从实体快照注入;wire 增加 POINT_CASTING_SPEED=21M2Client 暴露 casting_speedQuickbar 按 40250 两段公式换算冷却。五类 gate 与 casting_speed 数值回归通过;服务端拒绝后的冷却回滚、skill/group/quickslot/cooldown-end 乱序和完整动作包序仍保持 PARTIAL。"}
{"time":"2026-09-20T20:45:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["skill.player_ui_cooldown"],"files":["project/ui/quickbar.gd","project/playable_combat_test.gd","project/net_client_fake.gd","project/test_full_skill_flow.gd","audit/contracts/skill.player-ui-cooldown.md","audit/manifest.json"],"tests":["godot --headless --path project --script skill_test.gd","godot --headless --path project --script playable_combat_test.gd","godot --headless --path project --script mobile_gesture_test.gd","godot --headless --path project --script player_skill_test.gd","godot --headless --path project --script test_full_skill_flow.gd","git diff --check"],"reason":"按 40250 CPythonPlayer::__UseSkill / CPythonPlayerEventHandler::OnUseSkill 修复技能副作用顺序:先发送 FUNC_SKILL|motion + arg,再发送 CG_USE_SKILL(skill, target),动作状态成功后才触发本地 cast_started;同时补充共享 net_client_fake.gd 并让 full skill flow 实际断言 GameScene 装配和动作/意图包序。相关 Godot 回归通过;服务端拒绝/动作未起播后的冷却回滚、skill/group/quickslot/cooldown-end 乱序与跨生命周期、完整动作资源和服务端 damage 包序仍保持 PARTIAL。"}
{"time":"2026-09-20T20:52:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["skill.player_ui_cooldown"],"files":["project/player_skill.gd","project/net_play.gd","project/netplay_test.gd","project/ui/quickbar.gd","project/player_skill_test.gd","project/skill_test.gd","audit/contracts/skill.player-ui-cooldown.md","audit/manifest.json"],"tests":["godot --headless --path project --script player_skill_test.gd","godot --headless --path project --script skill_test.gd","godot --headless --path project --script netplay_test.gd","godot --headless --path project --script guild_war_skill_test.gd","git diff --check"],"reason":"按 40250 ClickSkillSlot→UseGuildSkill 分支修复公会技能:PlayerSkill 新增公会战状态/冷却检查,NetPlay 将 GUILD_WAR_ON_WAR=6 注入上下文,Quickbar 先发 FUNC_SKILL(loop=1) 再调用 M2Client.use_guild_skill(skill, 0),不再把 GUILD_ROUTED 静默丢弃。非公会战拒绝、公会战状态映射、独立包和公会 UI 回归通过;真实公会战回包、服务端拒绝/冷却回滚、跨生命周期乱序和完整动作/damage 证据仍保持 PARTIAL。"}
{"time":"2026-09-20T21:05:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["combat.target_selection_rules"],"files":["project/entity_rules.gd","project/net_play.gd","project/net_world.gd","project/player_controller.gd","project/netplay_test.gd","audit/contracts/combat.target-selection-rules.md","audit/manifest.json"],"tests":["godot --headless --path project --script netplay_test.gd","godot --headless --path project --script entity_rules_test.gd","godot --headless --path project --script playable_adapter_test.gd","godot --headless --path project --script test_click_target_effect_parity.gd","godot --headless --path project --script net_world_vis_test.gd","godot --headless --path project --script test_auto_combat_bot_parity.gd","godot --headless --path project --script playable_combat_test.gd","git diff --check"],"reason":"按 40250 CPythonPlayer::SetTarget 和 CInstanceBase::CanPickInstance 修复目标入口:先执行 CanChangeTarget(读取当前 .msa 的 WARP/FLY/EFFECT_TO_TARGET 事件),再执行重复目标 1/2 秒时间窗和统一 CanPickInstance;死亡/删除目标发出 CG_TARGET(0)NetWorld 将同一 can_pick 结果同步给 PlayerController 的点击与悬停路径,自动命中改走非强制 SetTarget 语义。目标门控和现有战斗/目标光圈回归通过;完整动作资源 live 时序、隐身/裁剪/迟到实体生命周期、地图 ATTRIBUTE_BANPK 权威、OnTargeted/飞行目标副作用和真实服务端包序仍保持 PARTIAL。"}
{"time":"2026-09-20T21:12:00Z","event":"audit_finding","result":"PARTIAL","ids":["combat.attack_combo_damage"],"files":["/Users/shen/Work/Code/Metin2/40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","/Users/shen/Work/Code/Metin2/40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseBattle.cpp","/Users/shen/Work/Code/Metin2/40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceBattle.cpp","/Users/shen/Work/Code/Metin2/40250/Server Client TMP4/ClientVS22/source/GameLib/WeaponTrace.cpp","project/net_play.gd","project/game_scene.gd","project/hit_collision.gd","audit/contracts/combat.attack-combo-damage.md","audit/manifest.json"],"tests":["godot --headless --path project --script combat_fx_test.gd","godot --headless --path project --script combat_parity_test.gd","godot --headless --path project --script gamescene_test.gd","ctest --test-dir build --output-on-failure","git diff --check"],"reason":"沿 CActorInstance::AttackingProcess -> __NormalAttackProcess -> OnHit 核对攻击链:状态包顺序、命中窗、fInvisibleTime/hit-limit 去重、受击反馈、弓箭 FLY 和换图队列有实现与回归证据;缺少 .msa/.msm 时当前端仍会合成近战命中,WeaponTrace 的骨骼采样/刀光生命周期未等价实现,真实服务端伤害/死亡/击退包序未 fixture 化,因此合同保持 PARTIAL。native CTest 首次串行出现一次 net.classic_encstream 加密头断言失败,单测复跑及全量复跑通过,暂记为时序/测试环境抖动。"}
{"time":"2026-09-20T21:20:00Z","event":"audit_finding","result":"PARTIAL","ids":["combat.death.exp_drop"],"files":["/Users/shen/Work/Code/Metin2/40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGame.cpp","/Users/shen/Work/Code/Metin2/40250/Server Client TMP4/ClientVS22/source/UserInterface/InstanceBaseBattle.cpp","/Users/shen/Work/Code/Metin2/40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","/Users/shen/Work/Code/Metin2/40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseGameItem.cpp","project/net_play.gd","project/net_world.gd","project/player_controller.gd","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","project/ui/ground_items.gd","audit/contracts/combat.death-exp-drop.md","audit/manifest.json"],"tests":["godot --headless --path project --script test_combat_death_pickup_entry_parity.gd","godot --headless --path project --script mob_death_drop_test.gd","godot --headless --path project --script combat_parity_test.gd","godot --headless --path project --script playable_combat_test.gd","godot --headless --path project --script gamescene_test.gd","./build/extension/net_state_queue_test","./build/extension/net_entity_test","git diff --check"],"reason":"回归核对 40250 的 GC_DEAD/Die/NotifyDead、POINT_EXP.amount、FLY_EXP 和地面掉落链:主角死亡输入门、自动攻击清理、复活边沿、死亡目标清理、经验增量一次性消费和掉落主路径均通过;真实服务端攻击到死亡/经验/掉落包序、重复/乱序/重连/拾取竞争、完整死亡资源生命周期和跨图清理仍未证明等价,合同保持 PARTIAL。"}
{"time":"2026-09-20T21:18:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["combat.attack_combo_damage"],"files":["project/net_play.gd","project/combat_fx_test.gd","project/netplay_test.gd","project/combat_parity_test.gd","project/playable_combat_test.gd","audit/contracts/combat.attack-combo-damage.md","audit/manifest.json"],"tests":["godot --headless --path project --script combat_fx_test.gd","godot --headless --path project --script netplay_test.gd","godot --headless --path project --script combat_parity_test.gd","godot --headless --path project --script playable_combat_test.gd","git diff --check"],"reason":"按 40250 CActorInstance::isValidAttacking 与 ActorInstanceCollisionDetection.cpp::__NormalAttackProcess 修复命中源:缺少 AttackingData/HitDataContainer、空命中窗或缺少 .msm 防御球时不再合成 CG_ATTACK;只有有效动作命中窗与真实防御球相交才进入 OnHit。相关反例与战斗回归通过;WeaponTrace 和真实服务端伤害/死亡/击退包序仍保持 PARTIAL。"}
{"time":"2026-09-20T21:24:34Z","event":"audit_finding","result":"PARTIAL","ids":["combat.attack_combo_damage"],"files":["/Users/shen/Work/Code/Metin2/40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceAttach.cpp","/Users/shen/Work/Code/Metin2/40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceWeaponTrace.cpp","/Users/shen/Work/Code/Metin2/40250/Server Client TMP4/ClientVS22/source/GameLib/WeaponTrace.cpp","/Users/shen/Work/Code/Metin2/40250/Server Client TMP4/ClientVS22/source/GameLib/WeaponTrace.h","/Users/shen/Work/Code/Metin2/40250/Server Client TMP4/ClientVS22/source/GameLib/ActorInstanceMotion.cpp","project/ui/player_view.gd","project/ui/equip_model.gd","project/socket_glow_fx_system.gd","audit/contracts/combat.attack-combo-damage.md","audit/manifest.json"],"tests":["godot --headless --path project --script player_motion_test.gd","godot --headless --path project --script combat_fx_test.gd","godot --headless --path project --script combat_parity_test.gd","godot --headless --path project --script playable_combat_test.gd","godot --headless --path project --script weapon_attach_test.gd","git diff --check"],"reason":"完成 WeaponTrace 全调用链核对:40250 具备按武器类型创建、INSTANCEBASE_Deform 每帧 TraceProcess、short/long 世界时间队列、reach scale 与 0.18s/0.003s 参数、cubic spline triangle strip、alpha/texture、攻击动作 Show/Hide 和 Destroy 清理;当前端没有对应生产实现,socket_glow_fx_system.has_trail 仅为未消费配置字段。动作/战斗回归通过;weapon_attach_test 仍有 race 0 的 03150 双手动作左手贴合失败并 exit 139,不能作为刀光等价证据。"}
{"time":"2026-09-20T21:35:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["combat.attack_combo_damage"],"files":["project/ui/weapon_trace.gd","project/ui/player_view.gd","project/ui/equip_model.gd","project/weapon_trace_test.gd","audit/contracts/combat.attack-combo-damage.md","audit/manifest.json"],"tests":["godot --headless --path project --script weapon_trace_test.gd","godot --headless --path project --script player_motion_test.gd","godot --headless --path project --script combat_fx_test.gd","godot --headless --path project --script combat_parity_test.gd","godot --headless --path project --script playable_combat_test.gd","godot --headless --path project --script netplay_test.gd","git diff --check"],"reason":"按 40250 ActorInstanceAttach/ActorInstanceWeaponTrace/WeaponTrace/Motion 调用边界接入 GDScript WeaponTrace:普通武器创建过滤、换装 detach/clear/free、攻击动作 TurnOn/TurnOff、short/long 世界采样队列、0.18s/0.003s cubic spline triangle strip、alpha/texture 材质与自然淡出均已有本地回归。当前端点仍由 Godot weapon AABB 推导而非 native bone matrix + reach scale,远端/怪物覆盖、真实视觉资源和服务端动作资源证据未完成;weapon_attach_test 的 race0/03150 左手贴合失败仍存在,因此结果为 PARTIAL。"}
{"time":"2026-09-20T21:36:23Z","event":"audit_finding","result":"PARTIAL","ids":["network.login.phase_flow"],"files":["/Users/shen/Work/Code/Metin2/40250/Server Client TMP4/ClientVS22/source/UserInterface/AccountConnector.cpp","/Users/shen/Work/Code/Metin2/40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStream.cpp","/Users/shen/Work/Code/Metin2/40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseLogin.cpp","/Users/shen/Work/Code/Metin2/40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseSelect.cpp","/Users/shen/Work/Code/Metin2/40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonNetworkStreamPhaseLoading.cpp","extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_stream.cpp","extension/src/net/classic/classic_parser.cpp","extension/src/net/m2_client.cpp","audit/contracts/network.login.phase-flow.md","audit/manifest.json"],"tests":["build/extension/net_classic_session_test","build/extension/net_classic_stream_test","build/extension/net_loopback_test","godot --headless --path project --script app_flow_lifecycle_test.gd","godot --headless --path project --script p10_test.gd","git diff --check"],"reason":"继续核对登录/握手/认证/选角/DirectEnter/Loading/PHASE_CLOSE:上述回归全部通过,且 TCP connect deadline 已存在;仍确认 phase deadline 缺失、m_pw/cfg_pw 在成功/失败/重连中保留而 40250 发送登录包后 ClearLoginInfo、PHASE_CLOSE 当前统一 Stage::Failed 而参考按 ClosePhase/DirectEnter 回到 Login/Offline、Matrix/Passpod/Hybrid 等可选分支明确 unsupported、真实服务端失败/重试/重复 phase/旧 stream 清理没有包级 fixture,因此合同保持 PARTIAL。"}
{"time":"2026-09-20T21:46:56Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow"],"files":["extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_session.h","extension/src/net/m2_client.cpp","extension/src/net/m2_client.h","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/manifest.json"],"tests":["cmake --build build -j2 --target net_classic_session_test mtgodot","build/extension/net_classic_session_test","build/extension/net_classic_stream_test","build/extension/net_classic_wire_test","build/extension/net_loopback_test","godot --headless --path project --script app_flow_lifecycle_test.gd","godot --headless --path project --script p10_test.gd","godot --headless --path project --script netplay_test.gd","git diff --check"],"reason":"按 40250 ClearLoginInfo 修复 CG_LOGIN/CG_LOGIN3 成功发送后的 session password 和 M2Client retry cache 清理;按 ClosePhase 清理旧 auth/game stream 并在 M2Client 区分登录侧 Login/Offline owner 与游戏侧 disconnected/reconnect。重新核对后确认 40250 m_dwChangingPhaseTime 没有 enforced phase deadline,因此不引入非参考行为。相关 native/Godot 回归通过;Matrix/Passpod/Hybrid 分支、真实失败/重复 phase/旧 stream fixture 和 Ubuntu 服务端包序仍保持 PARTIAL。"}
{"time":"2026-09-20T21:52:27Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.character_select.create_delete","network.packet_dispatch_protocol"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.character-select.md","audit/contracts/network.packet-dispatch.md","audit/manifest.json"],"tests":["cmake --build build -j2 --target net_classic_session_test","build/extension/net_classic_session_test","build/extension/net_classic_stream_test","build/extension/net_classic_wire_test","build/extension/net_loopback_test","godot --headless --path project --script char_create_delete_test.gd","godot --headless --path project --script test_intro_select_parity.gd","godot --headless --path project --script p10_test.gd","git diff --check"],"reason":"按 40250 LoginPhase/SelectPhase 的阶段 owner 修复角色创建、删除、改名回包的 Select/DirectEnter SelectPhase 门禁;错误阶段不再改写角色槽或派发角色 UI 事件,新增错误阶段反例测试。固定 3/4 槽、越界创建、未知改名 PID、帝国写入时点和 DirectEnter 不重复选人等既有差异已有修复证据;完整四阶段 allowlist、117-header 机器映射、locale codepage、异常双窗口、burst tick 和真实服务端包序仍保持 PARTIAL。"}
{"time":"2026-09-20T21:56:02Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.reconnect_warp"],"files":["extension/src/net/entity_store.h","extension/src/net/m2_client.cpp","extension/tests/net_entity_test.cpp","audit/contracts/network.reconnect-warp.md","audit/manifest.json"],"tests":["cmake --build build -j2 --target net_entity_test mtgodot","build/extension/net_entity_test","build/extension/net_classic_session_test","build/extension/net_loopback_test","godot --headless --path project --script p9_test.gd","godot --headless --path project --script gamescene_test.gd","godot --headless --path project --script p10_test.gd","godot --headless --path project --script app_flow_lifecycle_test.gd","git diff --check"],"reason":"按 40250 RecvWarpPacket 单次消费和同一连接替换语义修复 warp cue 队列:EntityStore 新增 FIFO take_next_warpclassic/legacy game 两条 M2Client 分支每次 pump 只取一个 warp,后续 cue 不再因第一个重连 return 被整批丢弃。双 warp 队列测试和重连/地图/UI 回归通过;真实旧新 socket 竞态、live 包序、实际连接超时、重复 reconnect/warp、datagram 注销和清理 owner 时序仍保持 PARTIAL。"}
{"time":"2026-09-20T22:05:24Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.error_timeout_server_state"],"files":["extension/src/net/auth_client.h","extension/src/net/net_stream.h","extension/src/net/net_stream.cpp","extension/src/net/classic/classic_stream.cpp","extension/src/net/m2_client.cpp","project/net/channel_status.gd","project/app_flow.gd","extension/tests/net_loopback_test.cpp","extension/tests/net_classic_stream_test.cpp","project/channel_status_test.gd","audit/contracts/network.error-timeout-server-state.md","audit/manifest.json"],"tests":["cmake --build build -j2 --target net_classic_stream_test net_loopback_test mtgodot","build/extension/net_classic_stream_test","build/extension/net_loopback_test","godot --headless --path project --script channel_status_test.gd","MT_PROTOCOL=classic godot --headless --path project --script channel_status_test.gd"],"reason":"按 40250 AccountConnector::ClearLoginInfo 清零 AuthClient 密码并同步清理 M2Client cfg_pw;按 EterLib CNetworkStream::Connect/Process 为 NetStream 与 ClassicStream 增加 3 秒连接 deadlineclassic 只在 select 可写后用 SO_ERROR 确认 Online;按 ServerStateChecker 单 probe 语义清理 ChannelStatus 旧 socket、固定 re-entrant callback,并给 AppFlow 增加 probe in-flight guard。新增挂起连接、密码清除和重入查询回归;成功及 classic/non-classic 状态夹具通过,认证失败、远端关闭、完整恢复和 count 边界仍保持 PARTIAL。"}
{"time":"2026-09-20T22:08:00Z","event":"test_run","result":"PARTIAL","ids":["network.error_timeout_server_state"],"tests":["ctest --test-dir build --output-on-failure","godot --headless --path project --script app_flow_lifecycle_test.gd","godot --headless --path project --script p10_test.gd","godot --headless --path project --script channel_status_test.gd","MT_PROTOCOL=classic godot --headless --path project --script channel_status_test.gd","git diff --check"],"reason":"23/23 native tests、AppFlow 生命周期、P10、默认和 classic 频道状态夹具及工作树空白检查全部通过;认证失败、远端关闭、完整恢复顺序、窗口销毁和 count 边界仍无完整证据,因此合同保持 PARTIAL。"}
{"time":"2026-09-20T22:20:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.packet_dispatch_protocol"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.packet-dispatch.md","audit/manifest.json"],"tests":["cmake --build build -j2 --target net_classic_session_test","build/extension/net_classic_session_test"],"reason":"按 40250 LoginPhase/SelectPhase/LoadingPhase 的 phase-local switch 增加 ClassicSession Login/Select/DirectEnter allowlistConnecting 保留真实游戏连接先收 LOGIN_SUCCESS3/4 的分支。错误阶段的 GC_CHARACTER_ADD 在进入 ClassicParser 前被拒绝,EntityStore 不再产生 spawn 副作用。测试补充 Login/Select 错误阶段反例并通过;Loading/Game 全量 allowlist、RecvErrorPacket 清缓冲语义、burst tick、117-header 机器映射和动态边界仍保持 PARTIAL。"}
{"time":"2026-09-20T22:21:00Z","event":"test_run","result":"PARTIAL","ids":["network.packet_dispatch_protocol"],"tests":["build/extension/net_classic_session_test","git diff --check"],"reason":"ClassicSession 阶段分发回归通过;其余 native/Godot 全量回归在上一轮已通过,但完整四阶段矩阵和 40250 单 tick/burst 事件顺序尚未建立。"}
{"time":"2026-09-20T22:28:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.packet_dispatch_protocol"],"files":["extension/src/net/classic/classic_stream.h","extension/src/net/classic/classic_stream.cpp","extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.packet-dispatch.md","audit/manifest.json"],"tests":["cmake --build build -j2 --target net_classic_session_test net_classic_stream_test","build/extension/net_classic_session_test","build/extension/net_classic_stream_test"],"reason":"按 40250 RecvErrorPacket 的消费/清缓冲语义,新增 ClassicStream 当前帧后清空剩余接收 buffer 的适配标记;Login/Select/DirectEnter allowlist 未命中不再断开 socket 或改变 phase owner,错误阶段 burst 中的后续游戏包也不会继续进入 EntityStore。测试覆盖错误阶段 spawn、角色回包和 trailing burst,并通过;parser/handler 真失败仍断线,Loading/Game 全量矩阵和 burst tick 仍保持 PARTIAL。"}
{"time":"2026-09-20T22:35:00Z","event":"test_run","result":"PARTIAL","ids":["network.packet_dispatch_protocol"],"tests":["cmake --build build -j2 --target mtgodot","ctest --test-dir build --output-on-failure","godot --headless --path project --script app_flow_lifecycle_test.gd","godot --headless --path project --script p10_test.gd","godot --headless --path project --script channel_status_test.gd","git diff --check","audit_ledger.py validate"],"reason":"mtgodot 构建通过,native 23/23、AppFlow 生命周期、P10、频道状态、工作树检查和 ledger validate 全部通过;packet dispatch 合同仍因 Loading/Game allowlist、burst tick、117 项映射和动态边界未闭合保持 PARTIAL。"}
{"time":"2026-09-21T22:45:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.packet_dispatch_protocol"],"files":["extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_stream.cpp","extension/tests/net_classic_session_test.cpp","extension/tests/net_classic_stream_test.cpp","audit/contracts/network.packet-dispatch.md","audit/manifest.json"],"tests":["cmake --build build -j2 --target net_classic_session_test net_classic_stream_test","build/extension/net_classic_session_test","build/extension/net_classic_stream_test"],"reason":"按 40250 LoadingPhase 的 Loading 专属分支与 GamePhase fallback、GamePhase 显式 switch、HybridCrypt 消费后返回和 phase/握手/密钥控制包立即 return 收口 ClassicSession/ClassicStream;新增 Loading/Game allowlist、拒绝矩阵、HybridCrypt 和 pipelined phase 边界回归并通过。GamePhase MAX_RECV_COUNT=4/SAFE_RECV_BUFSIZE=8192、117 项机器映射、动态声明长度算法及 handler 失败清理仍保持 PARTIAL。"}
{"time":"2026-09-21T23:00:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.packet_dispatch_protocol"],"files":["extension/src/net/classic/wire_classic.h","extension/src/net/classic/classic_parser.cpp","extension/src/net/classic/classic_stream.cpp","extension/tests/net_classic_session_test.cpp","extension/tests/net_classic_stream_test.cpp","audit/contracts/network.packet-dispatch.md","audit/manifest.json"],"tests":["cmake --build build -j2 --target net_classic_session_test net_classic_wire_test mtgodot","build/extension/net_classic_session_test","build/extension/net_classic_wire_test","ctest --test-dir build --output-on-failure","audit_packet_registry.py","git diff --check"],"reason":"继续按 40250 Packet.h/PythonNetworkStreamPhaseLoading 与 GamePhase 核对:补齐旧版 85 字节 HEADER_GC_MAIN_CHARACTER=15 的静态分帧和解析;ClassicStream 在 Game 阶段按 8192 字节阈值前的 MAX_RECV_COUNT 边界停止小 burst,下一 tick 再继续。回归通过;条件编译别名的 117 项完整机器映射、8192 字节以上 burst、动态声明长度和 handler 失败清理仍保持 PARTIAL。"}
{"time":"2026-09-21T23:20:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.packet_dispatch_protocol"],"files":["extension/src/net/classic/wire_classic.h","extension/src/net/classic/classic_session.cpp",".agents/skills/metin2-40250-parity-audit/scripts/audit_packet_registry.py","audit/contracts/network.packet-dispatch.md","audit/manifest.json","audit/history.jsonl"],"tests":["audit_packet_registry.py","git diff --check"],"reason":"读取 40250 Windows 工程条件编译后,按非 GAIDEN 分支实现主游戏包头数值/类别机器对照:参考 117 项与当前主流 117/117 对齐,删除攻击 12、旧更新 24、观察者 96/97/98、Panama 151 六个未注册普通流兼容分帧;保留 guild-mark 独立连接的 SYMBOL_DATA=133,并让审计脚本报告 numeric coverage、extra numeric values 和 kind mismatch。sizeof/byte layout、动态特殊消费和大 burst 仍保持 PARTIAL。"}
{"time":"2026-09-21T23:35:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.packet_dispatch_protocol"],"files":["extension/src/net/classic/classic_stream.cpp","extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.packet-dispatch.md","audit/manifest.json"],"tests":["cmake --build build -j2 --target net_classic_session_test net_classic_stream_test","build/extension/net_classic_session_test","build/extension/net_classic_stream_test"],"reason":"按 40250 RecvErrorPacket 修复已知包 handler 失败路径:当前帧消费后清空剩余接收 buffer,不再由该分支直接断开 socketClassicSession 不再因该类错误立即丢失 phase owner,未知 header/底层 framing 仍走硬失败。新增 unsupported integration 后下一 tick 可恢复解析的回归,native 测试通过。逐项布局、动态边界、大 burst 和应用退出副作用仍保持 PARTIAL。"}
{"time":"2026-09-21T23:50:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.packet_dispatch_protocol"],"files":["extension/src/net/classic/classic_stream.cpp","extension/tests/net_classic_stream_test.cpp","audit/contracts/network.packet-dispatch.md","audit/manifest.json"],"tests":["cmake --build build -j2 --target net_classic_stream_test","build/extension/net_classic_stream_test"],"reason":"按 40250 CheckPacket 修复前导零:只消费当前 header 前的连续 zero paddingzero-only buffer 等待下一次读取,非零 header 重新进入注册表检查;新增 zero-only 与 zero-run+valid packet 回归并通过。动态声明长度、逐项布局、8192 字节以上 burst 和未知包应用退出副作用仍保持 PARTIAL。"}
{"time":"2026-09-22T00:15:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.packet_dispatch_protocol"],"files":["extension/src/net/classic/classic_parser.cpp","extension/tests/net_classic_stream_test.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.packet-dispatch.md","audit/manifest.json"],"tests":["cmake --build build -j2 --target net_classic_stream_test net_classic_session_test","build/extension/net_classic_stream_test","build/extension/net_classic_session_test"],"reason":"沿 40250 CheckPacket -> Recv*Packet -> RecvErrorPacket 收紧动态 handler 的截断语义:SCRIPT、QUEST_INFO、MESSENGER、SHOP、GUILD、DUNGEON、NPC_POSITION、LAND_LIST、CHAT 的固定字段/记录尾部不足不再静默成功,而是返回失败并走当前帧消费、清空剩余缓冲、保留阶段 owner 的清理路径;QUEST_INFO 与 GUILD/SKILL_INFO 的已证实服务端特殊长度兼容仍保留。新增截断动态 SCRIPT 与 handler 失败后继续处理下一帧回归通过;13 项完整动态声明长度矩阵、逐项 sizeof/layout、大 burst 和应用退出副作用仍保持 PARTIAL。"}
{"time":"2026-09-22T00:30:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.packet_dispatch_protocol"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.packet-dispatch.md","audit/manifest.json"],"tests":["cmake --build build -j2 --target net_classic_session_test","build/extension/net_classic_session_test","git diff --check"],"reason":"按 40250 PythonNetworkStreamPhaseSelect.cpp::SelectPhase 修复 GC_PLAYER_POINT_CHANGE 的阶段副作用:Select/DirectEnter 只消费固定包并返回,不调用 RecvPointChange、不更新 EntityStoreLoading/Game 仍进入 parser 正常应用点数。新增选角阶段消费但无世界副作用回归;Loading/Game 完整 allowlist、逐项 sizeof/layout、动态声明长度矩阵和大 burst 仍保持 PARTIAL。"}
{"time":"2026-09-22T00:45:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.packet_dispatch_protocol"],"files":["extension/src/net/classic/classic_session.cpp",".agents/skills/metin2-40250-parity-audit/scripts/audit_phase_dispatch.py",".agents/skills/metin2-40250-parity-audit/SKILL.md","audit/contracts/network.packet-dispatch.md","audit/manifest.json","audit/history.jsonl"],"tests":["python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_phase_dispatch.py --strict","cmake --build build -j2 --target net_classic_session_test net_classic_stream_test","build/extension/net_classic_session_test","build/extension/net_classic_stream_test"],"reason":"新增按数值比较四阶段 payload 分支的自动审计,排除 ClassicStream 控制包和独立 observer stream 后 Login/Select/Loading/Game 均无缺失或额外 case;按 40250 LoadingPhase 的一次 GamePhase fallback 移除 Loading 对 21 号 ITEM_SET2 的专属分支,并移除已由 ClassicStream 消费的 HybridCrypt session allowlist。handler 副作用、逐项 sizeof/layout、动态声明长度矩阵和大 burst 仍保持 PARTIAL。"}
{"time":"2026-09-22T01:00:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["social.chat_text_tail"],"files":["extension/src/net/classic/classic_parser.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/social.chat-text-tail.md","audit/manifest.json","audit/history.jsonl"],"tests":["cmake --build build -j2 --target net_classic_session_test","build/extension/net_classic_session_test","git diff --check"],"reason":"按 40250 RecvChatPacket 的早返回分支收口 GC_CHAT:非法 chat type 直接消费,非系统消息的未知 chatter VID 直接消费不入队,已知 VID 仍正常产生 chat event;新增未知 VID、非法 type 和已知 VID 回归。表情解析、跨帝国转换、辱骂过滤、NOTICE/BIG_NOTICE UI、whisper mode 和 live ChatUI 仍保持 PARTIAL。"}
{"time":"2026-09-22T01:35:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["social.chat_text_tail"],"files":["project/ui/chat_ui.gd","project/chat_test.gd","audit/contracts/social.chat-text-tail.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script chat_test.gd","godot --headless --path project --script test_whisper_chat_parity.gd","godot --headless --path project --script chat_mobile_ui_test.gd","godot --headless --path project --script test_chat_hyperlink_dice_parity.gd","git diff --check"],"reason":"按 40250 CPythonChat::AppendWhisper 的按目标会话语义,把 live ChatUI 的普通/GM whisper_received 接入 WhisperChatSystem;收到消息前经过同一 ignore 状态判断,发送私聊也写入同一 conversation history,避免 helper 与实际 UI 各自维护私聊状态。窗口历史渲染、任务栏按钮、服务端 ignore 命令、完整颜色/通知和公共聊天副作用仍保持 PARTIAL。"}
{"time":"2026-09-22T01:45:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["social.chat_text_tail"],"files":["project/ui/chat_ui.gd","project/chat_test.gd","audit/contracts/social.chat-text-tail.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script chat_test.gd","git diff --check"],"reason":"继续追踪 40250 私聊的第二个入口:公共输入 `/w name text` 也已写入与独立私聊窗口相同的 WhisperChatSystem conversation,新增 Bob 会话历史回归,避免快捷入口和独立窗口形成两套本地私聊状态。完整窗口通知、服务端 ignore 命令、颜色和公共聊天副作用仍保持 PARTIAL。"}
{"time":"2026-09-22T02:00:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["lifecycle.bootstrap_phase_host"],"files":["project/ui/death_ui.gd","project/test_death_restart_parity.gd","audit/contracts/lifecycle.bootstrap-phase-host.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script test_death_restart_parity.gd","godot --headless --path project --script combat_fx_test.gd","git diff --check"],"reason":"按 40250 RecvPhasePacket 的 PHASE_DEAD 分支修正死亡入口:PHASE_DEAD 只消费阶段包,不产生 dead 阶段切换;DeathUI 移除不可达的 phase_changed(\"dead\") 监听,只由 GC_DEAD 派发的 entity_dead 打开。新增阶段误触发与真实死亡入口回归;GameOver/决斗例外、死亡动作、Loading reset、PHASE_CLOSE 和真实服务端包序仍保持 PARTIAL。"}
{"time":"2026-09-22T02:10:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["lifecycle.bootstrap_phase_host","world.reset_cleanup","network.reconnect_warp"],"files":["extension/src/net/classic/classic_session.h","extension/src/net/classic/classic_session.cpp","extension/src/net/m2_client.h","extension/src/net/m2_client.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/lifecycle.bootstrap-phase-host.md","audit/manifest.json","audit/history.jsonl"],"tests":["cmake --build build -j2 --target net_classic_session_test","build/extension/net_classic_session_test","git diff --check"],"reason":"按 40250 PythonNetworkStreamPhaseLoading.cpp::SetLoadingPhase 增加 classic on_loading_phase 回调:在 PHASE_LOADING 阶段 owner 切换时先清理仍存在的旧 EntityStore,并发出 world_reset,再接收后续出生包;GC_WARP 已提前清理时用空 world guard 避免重复 reset。native 回归证明旧主角被清理且新主角可正常建立;NetPlay/NetWorld/特效完整 owner 顺序和真实服务端包序仍保持 PARTIAL。"}
{"time":"2026-09-22T02:20:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.packet_dispatch_protocol","network.security_encoding"],"files":["extension/src/net/classic/classic_stream.cpp","audit/contracts/network.packet-dispatch.md","audit/manifest.json","audit/history.jsonl"],"tests":["cmake --build build -j2 --target net_classic_encstream_test net_classic_session_test","build/extension/net_classic_encstream_test","build/extension/net_classic_session_test","ctest --test-dir build --output-on-failure"],"reason":"全套 native 回归发现并修复阶段控制边界回归:KEY_AGREEMENT_COMPLETED 激活 CTR 后,必须继续解密并派发同一缓冲区中已经到达的密文;不能像 PHASE/初始密钥协商一样提前 return。net_classic_encstream_test 的 pipelined COMPLETED+encrypted packet 现已通过,完整回归其余协议测试通过;legacy TEA、HybridCrypt/SDB、Panama pack IV、Windows codepage 和真实服务端矩阵仍保持 PARTIAL。"}
{"time":"2026-09-20T00:00:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.reconnect_warp"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.reconnect-warp.md","audit/history.jsonl"],"tests":["cmake --build build -j2 --target net_classic_session_test","build/extension/net_classic_session_test","git diff --check"],"reason":"按 40250 PythonNetworkStreamPhaseGame::RecvWarpPacket -> CNetworkStream::Connect/Clear 的边界修复 classic GC_WARP:解析当前 warp 后立即清空同一接收缓冲中旧 socket 的尾包,避免在 M2Client 调用 connect_warp() 前污染新地图 EntityStore;新增 GC_WARP+GC_CHARACTER_ADD pipelined 回归。真实旧/新 socket 交错、legacy backend、重复 warp 和 datagram 注销仍保持 PARTIAL。"}
{"time":"2026-09-20T00:00:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.reconnect_warp"],"files":["extension/src/net/game_client.h","extension/tests/net_loopback_test.cpp","audit/contracts/network.reconnect-warp.md","audit/history.jsonl"],"tests":["cmake --build build -j2 --target net_loopback_test","build/extension/net_loopback_test","git diff --check"],"reason":"将同一 40250 GC_WARP 旧 socket 尾包边界同步到 legacy GameClientGC_WARP 已应用后立即 drop_recv()MockServer 在同一写入中追加 GC_CHARACTER_ADD 并新增断言,避免 legacy dispatcher 在 host 处理 warp 前污染 EntityStore。两套 backend 的重复 warp、真实新旧 socket 交错和 datagram 注销仍保持 PARTIAL。"}
{"time":"2026-09-20T00:00:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login_phase_flow","network.reconnect_warp"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/contracts/network.reconnect-warp.md","audit/history.jsonl"],"tests":["cmake --build build -j2 --target net_classic_session_test","build/extension/net_classic_session_test","git diff --check"],"reason":"按 40250 只有 PHASE_GAME 后才进入游戏 owner 的语义修复 classic 断线分类:不再把 TCP Online 当作 was_online_lost,改为收到 PHASE_GAME 时设置;新增真实 loopback 连接后、PHASE_GAME 前 peer close 回归,避免 DirectEnter/选人失败误进入局内重连。认证/握手/Loading 失败矩阵、真实服务器包序和完整 UI owner 仍保持 PARTIAL。"}
{"time":"2026-09-20T23:55:15Z","event":"implementation_fix_round","result":"PARTIAL","ids":["movement.click-collision"],"files":["project/player_controller.gd","project/player_move_test.gd","audit/contracts/movement.click-collision.md","audit/history.jsonl"],"tests":["godot --headless --path project --script player_move_test.gd","git diff --check"],"reason":"按 40250 __OnClickSmart 的无目标回退分支补齐空白点击停止:地面射线未命中且没有掉落物/实体时调用 stop(),清除旧点地目标和预约状态;新增空白点击后不再继续移动的回归。Smart 按住/自动模式、真实对象 picking 和 Actor 碰撞几何仍保持 PARTIAL。"}
{"time":"2026-09-20T23:55:15Z","event":"implementation_fix_round","result":"PARTIAL","ids":["movement.remote-sync-state"],"files":["extension/src/net/entity_store.cpp","extension/tests/net_state_queue_test.cpp","audit/contracts/movement.remote-sync-state.md","audit/history.jsonl"],"tests":["cmake --build build -j2 --target net_state_queue_test","build/extension/net_state_queue_test","git diff --check"],"reason":"按 40250 InstanceBase::StateProcess 补齐 FUNC_EMOTION 的独立 100cm 阈值:远端角色距离超过阈值先走到目标,到达后再恢复 FUNC_EMOTION/arg;远程表情移动不启用 skip-collision,并新增近距/远距回归。TPacketGCMove 不携带双人表情目标 VID,不可取消技能/表情锁和完整动作资源路由仍保持 PARTIAL。"}
{"time":"2026-09-20T23:55:15Z","event":"audit_round","result":"PARTIAL","ids":["world.npc-drop-actor-spawn"],"files":["audit/contracts/world.npc-drop-actor-spawn.md","audit/history.jsonl"],"tests":["godot --headless --path project --script net_world_vis_test.gd","git diff --check"],"reason":"复核旧审计记录中的可见性失败结论;当前 net_world_vis_test 已实际 PASS,已将合同中的过期 4 项失败改为基础可见性边沿已通过,并保留真实 actor manager 淡出、wall/always-show、资源失败和完整实体清理为 PARTIAL。"}
{"time":"2026-09-20T23:55:15Z","event":"implementation_fix_round","result":"PARTIAL","ids":["world.npc-drop-actor-spawn"],"files":["project/net_world.gd","project/net_world_vis_test.gd","audit/contracts/world.npc-drop-actor-spawn.md","audit/history.jsonl"],"tests":["godot --headless --path project --script net_world_vis_test.gd","godot --headless --path project --script net_world_vis_test.gd","godot --headless --path project --script player_move_test.gd","godot --headless --path project --script movement_parity_test.gd","git diff --check"],"reason":"按 40250 CPythonCharacterManager::Update 每帧执行距离剔除的实现,移除 NetWorld 固定 100ms 可见性节流,避免快速连续帧在进入/离开视野时产生不稳定的 stale node。连续两次可见性回归均通过;真实 actor manager 淡出、wall/always-show 复杂组合和资源失败仍保持 PARTIAL。"}
{"time":"2026-09-20T23:59:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["movement.remote-sync-state"],"files":["project/net_world.gd","project/net_world_remote_action_test.gd","audit/contracts/movement.remote-sync-state.md","audit/history.jsonl"],"tests":["godot --headless --path project --script net_world_remote_action_test.gd","git diff --check"],"reason":"按 40250 InstanceBase::StateProcess 到 RunNormalAttack/RunComboAttack 的动作选择修复远端状态表现:FUNC_ATTACK 使用 NAME_NORMAL_ATTACK 13FUNC_COMBO 原样保留 bArg 连击段,同时传递当前武器动作模式和攻速比例;资源缺失仍回退通用状态。不可取消技能门、表情/TCP 锁、技能 grade、TEMP_Push 和真实资源/服务器时序仍保持 PARTIAL。"}
{"time":"2026-09-21T00:04:00Z","event":"audit_round","result":"PARTIAL","ids":["network.packet_dispatch_protocol"],"files":["audit/contracts/network.packet-dispatch.md","audit/history.jsonl"],"tests":["python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_packet_registry.py","python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_phase_dispatch.py --strict","build/extension/net_classic_wire_test","build/extension/net_classic_stream_test","build/extension/net_classic_session_test"],"reason":"复核 40250 主表和四阶段 dispatch117/117 数值覆盖、104 静态/13 动态类别无 mismatch,阶段 payload 矩阵无缺失;native wire/stream/session 回归通过。动态声明长度全矩阵、逐项 sizeof/layout、8192 字节以上 burst 和 SYMBOL_DATA 独立连接边界仍保持 PARTIAL。"}
{"time":"2026-09-21T00:20:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["movement.remote-sync-state","skill.cast.effect_timing"],"files":["extension/src/net/entity_store.h","extension/src/net/entity_store.cpp","extension/src/net/m2_client.h","extension/src/net/m2_client.cpp","extension/tests/net_state_queue_test.cpp","project/net_world.gd","project/net_world_remote_action_test.gd","audit/contracts/movement.remote-sync-state.md","audit/history.jsonl"],"tests":["cmake --build build -j2 --target net_state_queue_test mtgodot","build/extension/net_state_queue_test","ctest --test-dir build --output-on-failure","godot --headless --path project --script net_world_remote_action_test.gd","godot --headless --path project --script net_world_vis_test.gd","godot --headless --path project --script netplay_test.gd","godot --headless --path project --script player_motion_test.gd","godot --headless --path project --script test_skill_state_arg_parity.gd","git diff --check"],"reason":"按 40250 __CanProcessNetworkStatePacket / __IsEnableTCPProcess 增加不可取消技能、活动表情和 TCP 状态门,并由 motion_bound(\"wait\") 释放;FUNC_EMOTION 的 uArg 接入实际动作 ID,出生时已有 FUNC_* 的实体在字段刷新后立即绑定动作;节点剔除/换图清门。完整 native 23/23 与关联 Godot 回归通过。技能可取消性权威动作数据、双人表情目标、真实资源尾时序和 TEMP_Push 仍保持 PARTIAL。"}
{"time":"2026-09-21T00:31:50Z","event":"implementation_fix_round","result":"PARTIAL","ids":["movement.remote_sync_state","skill.cast.effect_timing"],"files":["extension/src/net/entity_store.h","extension/src/net/entity_store.cpp","extension/src/net/m2_client.h","extension/src/net/m2_client.cpp","extension/tests/net_entity_test.cpp","project/net_world.gd","project/ui/player_view.gd","project/ui/mob_view.gd","project/net_world_remote_action_test.gd","audit/contracts/movement.remote-sync-state.md","audit/manifest.json","audit/history.jsonl"],"tests":["cmake --build build -j2 --target net_entity_test mtgodot","build/extension/net_entity_test","ctest --test-dir build --output-on-failure","godot --headless --path project --script net_world_remote_action_test.gd","godot --headless --path project --script net_world_vis_test.gd","godot --headless --path project --script netplay_test.gd","godot --headless --path project --script player_motion_test.gd","godot --headless --path project --script movement_parity_test.gd","python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_ledger.py validate","git diff --check"],"reason":"按 40250 NetworkActorManager::SyncActor -> NEW_SyncPixelPosition -> CActorInstance::TEMP_Push 补齐 GC_SYNC_POSITION 的纠偏链:EntityStore 记录源坐标、serial、150cm 大位移和技能抑制,NetWorld 执行最多 100 点地图碰撞探测、1 秒 BlendingPosition 偏移及 DAMAGE_FLYING -> STAND_UP 动作,并以 set_entity_knockdown 维持 IsKnockDown 网络门;动作尾、节点剔除和换图释放该门。原生 23/23、实体/动作/可见性/移动回归和审计校验通过;真实资源/地图碰撞、技能权威可取消性、双人表情目标和实服时序仍为 PARTIAL。"}
{"time":"2026-09-21T00:45:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["movement.keyboard.motion"],"files":["project/player_controller.gd","project/net_play.gd","project/keyboard_motion_timeline_test.gd","audit/contracts/movement.keyboard-motion.md","audit/history.jsonl"],"tests":["godot --headless --path project --script keyboard_motion_timeline_test.gd","godot --headless --path project --script test_wasd_steering_parity.gd","godot --headless --path project --script test_no_auto_move_regression.gd","godot --headless --path project --script player_move_test.gd","godot --headless --path project --script netplay_test.gd","python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_ledger.py validate","git diff --check"],"reason":"按 40250 CPythonPlayer::__CanMove、IsOpenPrivateShop、StartEmotionProcess/EndEmotionProcess 和 Update() 的 m_isDirKey 重试语义,补齐 PlayerController 的私店/情绪移动门;NetPlay 仅从主角 entity_info 的 shop_sign/acting_emotion 同步状态,保留 held WASD 并在门解除后的首帧恢复固定目标。输入、W/S 快切、自动移动、点地移动门和 NetPlay 回归通过;根运动事件源、相机副作用、同步/受击/传送完整边界和真实服时序仍为 PARTIAL。"}
{"time":"2026-09-21T00:48:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["movement.keyboard.motion","world.reset_cleanup"],"files":["project/net_play.gd","audit/contracts/movement.keyboard-motion.md","audit/history.jsonl"],"tests":["godot --headless --path project --script keyboard_motion_timeline_test.gd","godot --headless --path project --script netplay_test.gd","python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_ledger.py validate","git diff --check"],"reason":"按 40250 CPythonPlayer::Clear / SetMainCharacterIndex 的生命周期清理补齐换图和新主角建立时的私店、情绪状态复位,避免旧 entity_info 延迟包在新角色初始化前继续阻止移动;相关回归与账本校验通过,其余地图重置和完整状态时序仍为 PARTIAL。"}
{"time":"2026-09-22T02:35:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["skill.cast.effect_timing"],"files":["extension/src/metin2_anim.h","extension/src/metin2_anim.cpp","project/ui/player_view.gd","project/skill_motion_loop_test.gd","audit/contracts/skill.cast-effect-timing.md","audit/manifest.json","audit/history.jsonl"],"tests":["cmake --build build --target mtgodot -j4","godot --headless --path project --script skill_motion_loop_test.gd","godot --headless --path project --script skill_test.gd","godot --headless --path project --script test_skill_state_arg_parity.gd","godot --headless --path project --script net_world_remote_action_test.gd","godot --headless --path project --script effect_playback_test.gd","godot --headless --path project --script player_motion_test.gd","git diff --check"],"reason":"按 40250 CInstanceBase::NEW_UseSkill、CActorInstance::SetMotionLoopCount 和 CurrentMotionProcess 补齐 MSA LoopData 片段循环:正数 uMotLoopCount 覆盖资源默认次数,零使用 MotionLoopCount,片段回绕时重复派发动作事件并在 lead-in/loop/tail 完成后才 playback_finishedPlayerView 统一把本地/远端 loop count 传给原生播放器。回归覆盖 PlayerView 参数、真实 yeonsa.msa 的一次回绕、计数递减、尾部结束以及技能/远端/特效/动作视图;grade 权威来源和完整技能事件/挂点/结果链仍保持 PARTIAL。"}
{"time":"2026-09-22T03:10:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["render.effect_particle_motion"],"files":["formats/msa.h","formats/msa.cpp","formats/tests/msa_test.cpp","extension/src/metin2_anim.cpp","project/motion_event_payload_test.gd","audit/contracts/render.effect-particle-motion.md","audit/manifest.json","audit/history.jsonl"],"tests":["cmake --build build --target formats_msa_test mtgodot -j4","build/formats/formats_msa_test","godot --headless --path project --script motion_event_payload_test.gd","git diff --check"],"reason":"按 40250 RaceMotionDataEvent.h/RaceMotionData.cpp 补齐 MotionEvent 专用 payloadFLY 的 FlyFileName/FlyPosition/骨骼、SCREEN_WAVING 的 DuringTime/Power/AffectingRange、SPECIAL_ATTACKING 的持续时间/命中开关/攻击参数/碰撞球,以及 type 7/8/9 事件记录;native motion_event_detailed/get_events 完整传出字段。解析单测、真实 type 2/4/6/7 资产 native 字典回归通过;按 Actor 的远端事件路由、.fly 实例、splash 命中和 show/hide/warp 行为仍保持 PARTIAL。"}
{"time":"2026-09-22T03:18:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["render.effect_particle_motion"],"files":["project/ui/player_view.gd","project/ui/mob_view.gd","project/game_scene.gd","project/motion_event_visibility_test.gd","audit/contracts/render.effect-particle-motion.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script motion_event_visibility_test.gd","godot --headless --path project --script motion_event_payload_test.gd","build/formats/formats_msa_test","git diff --check"],"reason":"按 40250 CActorInstance::__HideEvent/__ShowEvent 接入本地主角 type 7/8 动作事件帧,并在 PlayerView/MobView 暴露 Actor 级可见性接口;本地显示/隐藏回归和 native 事件 payload 回归通过。远端 Actor 事件路由、type 4 splash、type 6 .fly、type 9 warp 和统一清理仍保持 PARTIAL。"}
{"time":"2026-09-22T03:32:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["render.effect_particle_motion"],"files":["project/net_world.gd","project/game_scene.gd","project/net_world_motion_event_test.gd","audit/contracts/render.effect-particle-motion.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script net_world_motion_event_test.gd","godot --headless --path project --script motion_event_visibility_test.gd","godot --headless --path project --script target_effect_test.gd","ctest --test-dir build --output-on-failure","git diff --check"],"reason":"按 40250 ActorInstanceMotionEvent 对每个可见 Actor 逐帧处理的边界,为 NetWorld 的真实远端 PC/NPC/Mob 接入 native motion_event_detailedGameScene 消费远端 type 1/10 FX、type 7/8 显示隐藏和 direct soundtype 6 保持服务端 GC_CREATE_FLY 权威,不伪造客户端发包。远端信号桥接、显示隐藏、目标 FX 和完整原生 23/23 回归通过;type 4 splash、.fly 实例、warp、震屏范围和统一清理仍保持 PARTIAL。"}
{"time":"2026-09-22T03:45:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["movement.motion_resource_events","render.effect_particle_motion"],"files":["project/game_scene.gd","project/motion_event_warp_test.gd","audit/contracts/movement.motion-resource-events.md","audit/contracts/render.effect-particle-motion.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script motion_event_warp_test.gd","python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_ledger.py validate","git diff --check"],"reason":"按 40250 ActorInstanceMotionEvent.cpp::ProcessMotionEventWarp 和 ActorInstanceEvent.cpp::__OnWarp 补齐 MotionEventType 9:目标前 270cm 的单位换算、地图阻挡拒绝、朝向目标,以及本地主角一次 FUNC_WAIT 状态包;远端 Actor 同样消费事件但不伪造本地网络包。真实 seomjeon.msa、可移动/阻挡/无目标分支回归通过;type 4 splash、type 6 .fly 数据权威、远端目标生命周期和统一跨图清理仍保持 PARTIAL。"}
{"time":"2026-09-22T04:05:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["combat.flying_projectile","render.effect_particle_motion"],"files":["project/fly_object.gd","project/net_world.gd","project/game_scene.gd","project/test_exp_fly_parity.gd","project/fly_data_msf_test.gd","audit/contracts/combat.flying-projectile.md","audit/contracts/render.effect-particle-motion.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script fly_data_msf_test.gd","godot --headless --path project --script test_exp_fly_parity.gd","godot --headless --path project --script fly_test.gd","godot --headless --path project --script fly_reset_test.gd","python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_ledger.py validate","git diff --check"],"reason":"按 40250 FlyingData.cpp::LoadScriptFile、PythonEffectModule.cpp、playersettingmodule.py 和 FlyingObjectManager::CreateIndexedFly 接入 .msf 字段解析、相对资源解析、cm→m 单位适配及索引飞行资源映射;修正 FLY_NONE/FLY_EXP 等枚举编号,并让 GC_CREATE_FLY 普通索引使用资源权威速度/射程/命中半径,不再按当前距离合成常量;单个 FLY_EXP 包按参考创建单个实例。资源/枚举/经验球/基础弹道/地图清理回归通过;动作事件 FLY 的 owner/skill/骨骼起点、动态 Actor 碰撞、FIRE_CRACKER/AUTO_FIRE 和 attach/tail 生命周期仍保持 PARTIAL。"}
{"time":"2026-09-22T04:30:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["world.entity_spawn_state_sync"],"files":["project/net_world.gd","project/net_world_respawn_test.gd","extension/src/net/entity_store.cpp","extension/tests/net_entity_test.cpp","audit/contracts/world.entity-spawn-state-sync.md","audit/manifest.json","audit/history.jsonl"],"tests":["cmake --build build --target net_entity_test -j4","build/extension/net_entity_test","godot --headless --path project --script net_world_respawn_test.gd --quit-after 10","godot --headless --path project --script net_world_vis_test.gd --quit-after 10","godot --headless --path project --script net_world_motion_event_test.gd --quit-after 10","godot --headless --path project --script net_world_remote_action_test.gd --quit-after 10","godot --headless --path project --script gamescene_test.gd --quit-after 10","godot --headless --path project --script combat_parity_test.gd --quit-after 10","godot --headless --path project --script playable_combat_test.gd --quit-after 10","godot --headless --path project --script netplay_test.gd --quit-after 10","ctest --test-dir build --output-on-failure","python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_ledger.py validate","git diff --check"],"reason":"按 40250 NetworkActorManager::__AppendCharacterManagerActor 的同 VID 重建分支,普通重建改用新包坐标/朝向,仅上下马状态切换保留旧位置;按 CPythonNetworkStream::RecvMainCharacter 与主实例注册边沿,首次主角发出 Spawn 后一次 MainSet,重复主角包只发一次 MainSet。新增普通重建/上下马边界和主角通知次数回归;修复后 native 23/23 与相关 Godot 回归通过。Add2 隐身种族、AdditionalInfo 未命中、旧 Add 字段完整性、淡出期间同 VID 重用和主 VID 切换清理仍保持 PARTIAL。"}
{"time":"2026-09-22T05:10:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["world.entity_spawn_state_sync"],"files":["extension/src/net/entity_store.cpp","extension/src/net/entity_store.h","extension/src/net/classic/classic_parser.cpp","extension/tests/net_entity_test.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/world.entity-spawn-state-sync.md","audit/manifest.json","audit/history.jsonl"],"tests":["cmake --build build --target net_entity_test net_classic_session_test -j2","build/extension/net_entity_test","build/extension/net_classic_session_test","python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_ledger.py validate","git diff --check"],"reason":"按 40250 PythonNetworkStreamPhaseGameActor 的 Add/Add2/AdditionalInfo/Update 完整字段链修复:classic 旧 Add 非 PC/NPC 保留 state/affectclassic 与 generic Add2 过滤 20025/20038/20039 并一次性保存 name、parts、state、affect、empire、guild、alignment、PK、mountclassic/generic Update 通过 shared mutator 一次更新完整字段并发一次 Infogeneric AdditionalInfo 未知 VID 不再 touch 创建半实体。修复前新增回归复现字段丢失、隐身实体、unknown AdditionalInfo 半实体和事件差异;修复后两个 native 回归通过。pending 交错清理、淡出期间同 VID 重用、主 VID 切换清理和 Godot 可见性时序仍保持 PARTIAL。"}
{"time":"2026-09-22T05:35:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["world.entity_spawn_state_sync"],"files":["project/net_world.gd","project/net_world_respawn_test.gd","audit/contracts/world.entity-spawn-state-sync.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script net_world_respawn_test.gd","python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_ledger.py validate","git diff --check"],"reason":"按 40250 RemoveActor -> DeleteInstanceByFade 与后续 AppendActor -> __AppendCharacterManagerActor 的生命周期修复淡出竞态:旧节点继续 fade,但同 VID 新 Spawn 解除旧 _fading 门控并立即建立 live replacement;旧 tween 完成时不删除新节点。修复前 net_world_respawn_test 可复现淡出期间新 Spawn 被直接丢弃,修复后覆盖立即重建、新位置和旧 tween 完成后的新节点存活。pending 交错清理、旧 dead-list/tween 跨帧并存、主 VID 切换清理和 Godot 可见性时序仍保持 PARTIAL。"}
{"time":"2026-09-22T05:55:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["world.entity_spawn_state_sync"],"files":["extension/src/net/classic/classic_parser.h","extension/src/net/classic/classic_parser.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/world.entity-spawn-state-sync.md","audit/manifest.json","audit/history.jsonl"],"tests":["cmake --build build --target net_classic_session_test net_entity_test -j2","build/extension/net_classic_session_test","build/extension/net_entity_test","python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_ledger.py validate","git diff --check"],"reason":"按 40250 PythonNetworkStreamPhaseGameActor::RecvCharacterAppendPacket 的 static SNetworkActorData s_kNetActorData 和 AdditionalInfo VID 匹配分支,将 classic pending 从 keyed map 收敛为单个 optional 槽;后一个旧 Add 覆盖前一个,被覆盖 VID 的迟到 AdditionalInfo 不创建实体。修复前交错 Add 回归复现两个 pending 和第一个 VID 错误生成,修复后两个 native 测试通过。Delete 后迟到 AdditionalInfo、map reset 后迟到包、主 VID 清理和 Godot 可见性/渲染副作用仍保持 PARTIAL。"}
{"time":"2026-09-22T06:15:00Z","event":"audit_evidence_reconciliation","result":"PARTIAL","ids":["world.entity_spawn_state_sync"],"files":["project/net_world.gd","project/net_world_vis_test.gd","extension/src/net/m2_client.cpp","audit/contracts/world.entity-spawn-state-sync.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script net_world_vis_test.gd","python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_ledger.py validate","git diff --check"],"reason":"按当前工作树重新验证可见性与 Add2 事件粒度:NetWorld._process 已逐帧执行 _update_visibilitynet_world_vis_test 覆盖进入范围建模、单次建模、离开范围淡出、数据层保留和重新进入并通过;classic Add2 现由 mut_spawn_full 产生单次完整 Spawn。修正旧审计中已过时的 100ms 节流、4 项可见性失败和 Add2 Spawn/Info/affect 拆分描述;Delete/map reset 后迟到包、主 VID 清理和渲染副作用顺序仍为 PARTIAL。"}
{"time":"2026-09-22T06:45:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["world.reset_cleanup"],"files":["project/net_world.gd","project/net_world_reset_test.gd","project/screen_hp_bar_test.gd","audit/contracts/world.reset-cleanup.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script net_world_reset_test.gd (pre-fix: 3 failures; post-fix: PASS)","godot --headless --path project --script screen_hp_bar_test.gd","python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_ledger.py validate","git diff --check"],"reason":"按 40250 CPythonNetworkStream::SetLoadingPhase 与 NetworkActorManager 清理边界,修复 NetWorld 换图后模型升级队列、聊天尾标、target/hover VID 和 target effect 残留;修正 screen_hp_bar_test 对死亡后已移除 HP 控件的 previously freed 访问,按 Die/DetachTextTail 语义验证控件移除并通过 entity_info 重建呈现。统一 reset generation、断线显式 world_reset、旧新地图顺序、通用特效 manager 和 rendering_scenario 退出码 139 仍保持 PARTIAL。"}
{"time":"2026-09-22T07:10:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["world.reset_cleanup"],"files":["project/game_scene.gd","project/rendering_scenario_test.gd","audit/contracts/world.reset-cleanup.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script gamescene_test.gd","MT_RENDER_SAMPLE_FRAMES=90 godot --headless --path project --script rendering_scenario_test.gd (failures=0, exit=139, 54 ObjectDB leaks)","python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_ledger.py validate","git diff --check"],"reason":"按 40250 CMapManager::UnloadMap / CPythonApplication::Destroy 顺序,GameScene 换图改为旧 Metin2World 先 unload_map 再 queue_free,场景 _exit_tree 显式卸载当前 world;渲染回归清理改为 world_reset -> unload -> frame-boundary SceneTree release。静态旧新地图顺序差异已修复,但 native model/resource 最终释放仍报告 54 个 ObjectDB 泄漏并以 139 退出,故合同继续 PARTIAL。"}
{"time":"2026-09-22T07:20:00Z","event":"audit_evidence_reconciliation","result":"PARTIAL","ids":["network.packet_dispatch_protocol"],"files":["extension/src/net/classic/wire_classic.h","extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_stream.cpp",".agents/skills/metin2-40250-parity-audit/scripts/audit_packet_registry.py",".agents/skills/metin2-40250-parity-audit/scripts/audit_phase_dispatch.py","audit/contracts/network.packet-dispatch.md","audit/history.jsonl"],"tests":["python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_packet_registry.py --repo-root .","python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_phase_dispatch.py --repo-root .","ctest --test-dir build --output-on-failure","git diff --check"],"reason":"当前主游戏流按数值覆盖 40250 有效 GC 注册项 117/117,静态/动态类别无 mismatchLogin/Select/Loading/Game payload case 数值无缺失或额外。HDR_GC_SYMBOL_DATA=133 仍为独立 guild-mark 适配;逐项 sizeof/byte layout、动态边界、8192 字节 burst、handler 副作用和失败清理仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-22T07:40:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["world.reset_cleanup"],"files":["extension/src/register_types.cpp","project/app_flow.gd","project/rendering_scenario_test.gd","audit/contracts/world.reset-cleanup.md","audit/manifest.json","audit/history.jsonl"],"tests":["MT_RENDER_SAMPLE_FRAMES=90 godot --headless --path project --script rendering_scenario_test.gd (pre-fix: failures=0, exit=139, 54 ObjectDB leaks; post-fix: exit=0, no ObjectDB leak)","godot --headless --path project --script app_flow_lifecycle_test.gd","cmake --build build -j4","python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_ledger.py validate","git diff --check"],"reason":"按 40250 CPythonApplication::Destroy 的进程级 manager 释放边界,接入 AppFlow._exit_tree 和 GDExtension terminator 的模型纹理、动作片段、NPC 模型规格及 UI 纹理缓存清理;渲染回归由 139/54 个 ObjectDB 泄漏变为干净退出。fly_reset 的 5 个 ObjectDB 泄漏、统一 generation、断线显式 world_reset 和通用 EffectManager 仍保持 PARTIAL。"}
{"time":"2026-09-22T07:55:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["world.reset_cleanup","combat.flying_projectile"],"files":["project/fly_object.gd","project/fly_reset_test.gd","project/test_exp_fly_parity.gd","audit/contracts/world.reset-cleanup.md","audit/contracts/combat.flying-projectile.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script fly_reset_test.gd (pre-fix: 5 ObjectDB leaks; post-fix: exit 0, no ObjectDB leak)","godot --headless --path project --script fly_data_msf_test.gd","godot --headless --path project --script fly_test.gd","godot --headless --path project --script test_exp_fly_parity.gd (6/6 PASS, 3 legacy fixture warnings remain)","python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_ledger.py validate","git diff --check"],"reason":"按 40250 CFlyingManager::DeleteAllInstances 的同步删除边界,解除 FlyInstance.handler 自捕获 RefCounted 环,并在地图清理/自然过期路径同步释放目标、world、data 及视觉节点;fly_reset 的 5 个 ObjectDB 泄漏已清零。动作事件 FLY 起点、动态 Actor 碰撞、真实包序、统一 reset generation、断线 world_reset 和通用 EffectManager 仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-22T08:20:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.reconnect_warp","world.reset_cleanup"],"files":["extension/src/net/m2_client.cpp","project/disconnect_world_reset_test.gd","project/netbridge_test.gd","audit/contracts/network.reconnect-warp.md","audit/contracts/world.reset-cleanup.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script disconnect_world_reset_test.gd (pre-fix: 2 failures; post-fix: PASS)","godot --headless --path project --script app_flow_lifecycle_test.gd","godot --headless --path project --script netbridge_test.gd (ObjectDB warning fixed by explicit fixture cleanup)","cmake --build build-debug --target mtgodot -j4","python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_ledger.py validate","git diff --check"],"reason":"按 40250 SetOffLinePhase/LeaveGamePhase 的先清 phase owner、后清 transport 顺序,M2Client::disconnect_from_server 现在先 reset 活动 EntityStore、发 world_reset,再释放 auth/game/classic session;保留 GameScene 的显式断开不会遗留旧 Actor/飞行/目标/UI 状态。新增回归先复现两项失败后通过,并清理 netbridge fixture 的 5 个 ObjectDB 警告。真实断线/GC_WARP 包序、统一 generation、旧新 socket 竞态和通用 EffectManager 仍保持 PARTIAL。"}
{"time":"2026-09-22T08:35:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["world.reset_cleanup","audio.bgm_ambience_3d"],"files":["project/audio.gd","project/game_scene.gd","project/rendering_scenario_test.gd","audit/contracts/world.reset-cleanup.md","audit/contracts/audio.bgm-ambience-3d.md","audit/manifest.json","audit/history.jsonl"],"tests":["MT_RENDER_SAMPLE_FRAMES=90 godot --headless --path project --script rendering_scenario_test.gd (Debug pre-fix: failures=0, exit=0, 2 AudioStreamMP3/AudioStreamPlaybackMP3 leaks; post-fix: exit=0, no ObjectDB leak)","godot --headless --path project --script audio_miles_test.gd","python3 .agents/skills/metin2-40250-parity-audit/scripts/audit_ledger.py validate","git diff --check"],"reason":"按 40250 CSoundManager::Destroy 的进程退出边界,新增 Audio.shutdown(),停止 BGM/3D 播放器、解除 player stream 并清空 MP3/MSS cacheGameScene._exit_tree 在 native world unload 前调用该 shutdown。Debug 真实资源渲染回归的 2 个音频 ObjectDB 泄漏已清零;地图/环境/声音完整时序和 Miles 实例池其余差异仍使合同保持 PARTIAL。"}
{"time":"2026-09-22T08:50:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["audio.bgm_ambience_3d"],"files":["project/app_lifecycle.gd","project/bgm_test.gd","audit/contracts/audio.bgm-ambience-3d.md","audit/manifest.json","audit/history.jsonl"],"tests":["project/bgm_test.gd pre-fix: 1 failure, master_sfx remained 0.9 after background entry","godot --headless --path project --script bgm_test.gd (post-fix PASS)","godot --headless --path project --script audio_miles_test.gd (PASS)","godot --headless --path project --script app_flow_lifecycle_test.gd (PASS)","godot --headless --path project --script disconnect_world_reset_test.gd (PASS)","godot --headless --path project --script netbridge_test.gd (PASS)"],"reason":"按 40250 CSoundManager::SaveVolume/RestoreVolume 的双通道音量语义,AppLifecycle._enter_background 在保存备份后同时静音 BGM 与 SFXbgm_test 新增后台 SFX=0 断言并在修复前复现失败,修复后通过。Miles 固定实例池、BGM 多实例状态机和真实 3D 播放器边界仍保持 PARTIAL。"}
{"time":"2026-09-22T09:10:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["lifecycle.platform_release","audio.bgm_ambience_3d"],"files":["project/app_lifecycle.gd","project/bgm_test.gd","audit/contracts/lifecycle.platform-release.md","audit/contracts/audio.bgm-ambience-3d.md","audit/manifest.json","audit/history.jsonl"],"tests":["project/bgm_test.gd pre-fix: 2 failures because window focus-out did not mute BGM/SFX","godot --headless --path project --script bgm_test.gd (post-fix PASS)","godot --headless --path project --script app_flow_lifecycle_test.gd (PASS)","godot --headless --path project --script mouse_controller_test.gd (PASS)","godot --headless --path project --script audio_miles_test.gd (PASS)"],"reason":"按 40250 CPythonApplication::WindowProcedure 的 WM_ACTIVATEAPP 分支,AppLifecycle 对 application/window focus-out/in 现在统一复用后台进入/退出路径,保存并静音 BGM/SFX 后恢复备份值;_bg 守卫覆盖 pause/focus 重复通知。Windows 全屏、WM_SIZE/back-buffer、导出、CRC 和异常发布链仍保持 PARTIAL。"}
{"time":"2026-09-22T09:30:00Z","event":"audit_evidence_reconciliation","result":"PARTIAL","ids":["world.environment_weather"],"files":["project/environment_test.gd","project/skybox_test.gd","project/p9_test.gd","project/test_weather_daynight_parity.gd","project/game_scene.gd","project/weather_daynight_system.gd","audit/contracts/world.environment-weather.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script environment_test.gd (PASS; A1 .msenv runtime load)","godot --headless --path project --script skybox_test.gd (PASS; CapeDragonHead/DawnMistWood six-face sky)","godot --headless --path project --script p9_test.gd (PASS; generic weather switch)","godot --headless --path project --script test_weather_daynight_parity.gd (22/22 PASS; isolated helper only)"],"reason":"复核 40250 MapOutdoorRender/SnowEnvironment/SkyBox/ScreenFilter/LensFlare 调用链与当前 GameScene::_build_world/Weather/WeatherDayNightSystem.msenv、天空、基础粒子链路有运行证据,但正式场景未消费 WeatherDayNightSystemfilter/lens flare/wind、线性 fog、SnowEnvironment 池和真实 render-order 仍未等价,合同继续 PARTIAL。"}
{"time":"2026-09-22T10:00:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["world.environment_weather","world.reset_cleanup"],"files":["extension/src/net/entity_store.h","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","extension/tests/net_entity_test.cpp","project/game_scene.gd","project/gamescene_test.gd","project/netbridge_test.gd","audit/contracts/world.environment-weather.md","audit/manifest.json","audit/history.jsonl"],"tests":["gamescene_test.gd pre-fix: xmas_snow=1 eligible-map assertion failed","build/extension/net_entity_test (post-fix all checks passed)","godot --headless --path project --script gamescene_test.gd (PASS)","godot --headless --path project --script netbridge_test.gd (PASS)","godot --headless --path project --script p9_test.gd (PASS)","godot --headless --path project --script environment_test.gd (PASS)","cmake --build build --target net_entity_test -j4 (PASS)","cmake --build build-debug --target mtgodot -j4 (PASS)"],"reason":"按 40250 ServerCommandParser.__XMasSnow_Enable -> game.__XMasSnow_Enable -> background.EnableSnow 复刻服务器 xmas_snow 0/1:新增 EntityStore WeatherChanged typed event 与 M2Client.weather_changed 信号,GameScene 按 __IsXMasMap 的四张排除地图启停雪粒子,并在换图后重算。命令解析、生产场景接线和桥接信号回归通过;当前 GPUParticles3D 仍不等价于 SnowEnvironment 池,DayMode、filter/lens flare/wind、线性 fog 仍保持 PARTIAL/GAP。"}
{"time":"2026-09-21T03:23:08Z","event":"audit_evidence_reconciliation","result":"PARTIAL","ids":["combat.death.exp_drop"],"files":["../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayer.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonPlayerInput.cpp","../40250/Server Client TMP4/ClientVS22/source/UserInterface/PythonItem.cpp","project/ui/ground_items.gd","project/net_play.gd","extension/src/net/entity_store.cpp","audit/contracts/combat.death-exp-drop.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script test_combat_death_pickup_entry_parity.gd --quit-after 10 (PASS)","godot --headless --path project --script mob_death_drop_test.gd --quit-after 10 (PASS)","godot --headless --path project --script combat_parity_test.gd --quit-after 10 (PASS)","godot --headless --path project --script playable_combat_test.gd --quit-after 10 (PASS)","godot --headless --path project --script gamescene_test.gd --quit-after 10 (PASS; expected no_such_map fixture warning)","build/extension/net_state_queue_test (PASS)"],"reason":"继续对照 40250 PickCloseItem -> SendClickItemPacket -> GetOwnership/IsPartyMemberByName/ITEM_ANTIFLAG 与当前 GroundItems/NetPlay/EntityStore:确认本人掉落、GC_ITEM_GROUND_ADD/DEL、经验增量和死亡门回归通过;记录 party owner/anti-flag 预检缺失、DISTANCE_APPROX/300cm 与 Godot 欧氏 3/5m 规则不同、try_pickup_vid 公开入口缺少自身距离门。真实服务端攻击→死亡→POINT_EXP→CREATE_FLY→掉落包序、重复/乱序/重连和跨图清理仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T03:30:44Z","event":"implementation_fix_round","result":"PARTIAL","ids":["combat.death.exp_drop"],"files":["project/ui/ground_items.gd","project/net_play.gd","project/test_ground_pickup_parity.gd","project/netplay_test.gd","audit/contracts/combat.death-exp-drop.md","audit/manifest.json","audit/history.jsonl"],"tests":["project/test_ground_pickup_parity.gd pre-fix: 6 failures (party owner, DISTANCE_APPROX diagonal, VID tie-break, try_pickup_vid distance gate)","godot --headless --path project --script test_ground_pickup_parity.gd --quit-after 10 (PASS)","godot --headless --path project --script netplay_test.gd --quit-after 10 (PASS)","godot --headless --path project --script mob_death_drop_test.gd --quit-after 10 (PASS)","godot --headless --path project --script test_combat_death_pickup_entry_parity.gd --quit-after 10 (PASS)"],"reason":"按 40250 CPythonPlayer::SendClickItemPacket、CPythonItem::GetCloseItem 和 CPythonPlayer::__OnPressItem 修复 GroundItems:保存/读取 anti_flags,允许无 DROP/GIVE anti-flag 的队伍成员 owner,使用固定 300cm DISTANCE_APPROX 和最高 VID tie-breaktry_pickup_vid 与 NetPlay 点击预约统一为 150cm 且边界包含。真实服务端死亡/掉落包序、重连 catch-up、空 owner/重名和拾取竞争仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T03:38:29Z","event":"implementation_fix_round","result":"PARTIAL","ids":["skill.cast.effect_timing"],"files":["project/ui/skill_table.gd","project/ui/quickbar.gd","project/net_world.gd","project/skill_test.gd","project/net_world_remote_action_test.gd","audit/contracts/skill.cast-effect-timing.md","audit/manifest.json","audit/history.jsonl"],"tests":["project/skill_test.gd pre-fix: 1 failure (missing grade motion-index API)","godot --headless --path project --script skill_test.gd --quit-after 10 (PASS)","godot --headless --path project --script net_world_remote_action_test.gd --quit-after 10 (PASS)","godot --headless --path project --script test_skill_state_arg_parity.gd --quit-after 10 (PASS)","godot --headless --path project --script skill_motion_loop_test.gd --quit-after 10 (PASS)","godot --headless --path project --script skill_fx_test.gd --quit-after 10 (PASS)","godot --headless --path project --script combat_fx_test.gd --quit-after 10 (PASS)"],"reason":"按 40250 CPythonSkill::GetSkillMotionIndex、SKILL_EFFECT_COUNT=4、SKILL_GRADEGAP=25 以及当前 constinfo.py 开启的 USE_SKILL_EFFECT_UPGRADE_ENABLE=1,补齐等级动作索引。Quickbar 本地普通技能按 master grade 发送 base+grade*25NetWorld 远端按 FUNC_SKILL motion index 反解 grade 后选择对应 MSA;公会技能保留基础索引。逐技能 MSA/MSE 事件、服务端结果和完整中断清理仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T03:42:22Z","event":"implementation_fix_round","result":"PARTIAL","ids":["combat.attack_combo_damage"],"files":["project/net_world.gd","project/damage_local_main_parity_test.gd","audit/contracts/combat.attack-combo-damage.md","audit/manifest.json","audit/history.jsonl"],"tests":["project/damage_local_main_parity_test.gd pre-fix: 1 failure (MainInstance damage billboard was dropped because _by_vid excludes the local node)","godot --headless --path project --script damage_local_main_parity_test.gd --quit-after 10 (PASS)"],"reason":"按 40250 RecvDamageInfoPacket -> MainInstance::AddDamageEffect -> ProcessDamage 修复本地主角伤害显示:NetWorld 处理 damage 队列时对本地 VID 回退到 _local_node。服务端真实伤害/死亡包、WeaponTrace 坐标端点、远端/怪物覆盖和攻击生命周期清理仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T03:46:11Z","event":"implementation_fix_round","result":"PARTIAL","ids":["combat.attack_combo_damage"],"files":["project/ui/player_view.gd","project/weapon_trace_multi_part_parity_test.gd","audit/contracts/combat.attack-combo-damage.md","audit/manifest.json","audit/history.jsonl"],"tests":["project/weapon_trace_multi_part_parity_test.gd pre-fix: 1 failure (PlayerView only created one trace from Weapon and dropped Shield)","godot --headless --path project --script weapon_trace_multi_part_parity_test.gd --quit-after 10 (PASS)","godot --headless --path project --script weapon_trace_test.gd --quit-after 10 (PASS)","godot --headless --path project --script equip_model_test.gd --quit-after 10 (PASS)","godot --headless --path project --script weapon_attach_test.gd --quit-after 10 (PASS)","godot --headless --path project --script player_motion_test.gd --quit-after 10 (PASS)","godot --headless --path project --script combat_fx_test.gd --quit-after 10 (PASS)"],"reason":"按 40250 ActorInstanceAttach 的双部件 AttachWeapon 与 m_WeaponTraceVector 修复 PlayerViewWeapon/Shield 每个部件各自创建并维护 WeaponTraceTurnOn/TurnOff、detach、纹理、Texture/Alpha 模式控制均逐部件广播。骨骼矩阵 + reach scale 端点、远端/怪物覆盖和服务端攻击闭环仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T03:48:09Z","event":"audit_evidence_reconciliation","result":"PARTIAL","ids":["item.inventory_equipment_state"],"files":["audit/contracts/item.inventory-equipment-state.md","audit/manifest.json","audit/history.jsonl"],"tests":["build/extension/net_bounds_test (PASS)","build/extension/net_entity_test (PASS)","build/extension/net_classic_session_test (PASS)","godot --headless --path project --script inventory_ui_test.gd --quit-after 10 (PASS)","godot --headless --path project --script equip_model_test.gd --quit-after 10 (PASS)","godot --headless --path project --script item_tooltip_test.gd --quit-after 10 (PASS)","godot --headless --path project --script view_equipment_ui_test.gd --quit-after 10 (PASS; 5 ObjectDB instances leaked at exit)"],"reason":"重新核对 40250 物品收发包、行动门、Set2 高亮、Update 双快照与当前 EntityStore/M2Client/InventoryUI:已实现部分没有回归;物品音效/SendSequence、服务器拒绝回滚、扩展槽位乱序/换图重建和干净生命周期仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T03:55:25Z","event":"implementation_fix_round","result":"PARTIAL","ids":["combat.attack_combo_damage"],"files":["project/ui/weapon_trace.gd","project/ui/player_view.gd","project/net_play.gd","project/weapon_trace_endpoint_parity_test.gd","project/weapon_trace_reach_affect_parity_test.gd","project/weapon_reach_scale_attack_parity_test.gd","audit/contracts/combat.attack-combo-damage.md","audit/manifest.json","audit/history.jsonl"],"tests":["project/weapon_trace_endpoint_parity_test.gd pre-fix: endpoint direction/length failures and missing set_reach_scale API","project/weapon_trace_reach_affect_parity_test.gd pre-fix: AFFECT_GEOMGYEONG did not change WeaponTrace reach scale","project/weapon_reach_scale_attack_parity_test.gd pre-fix: attack sample path had no reach-scaled endpoint helper","godot --headless --path project --script weapon_trace_endpoint_parity_test.gd --quit-after 10 (PASS)","godot --headless --path project --script weapon_trace_reach_affect_parity_test.gd --quit-after 10 (PASS)","godot --headless --path project --script weapon_reach_scale_attack_parity_test.gd --quit-after 10 (PASS)","godot --headless --path project --script weapon_trace_multi_part_parity_test.gd --quit-after 10 (PASS)","godot --headless --path project --script weapon_trace_test.gd --quit-after 10 (PASS)","godot --headless --path project --script combat_fx_test.gd --quit-after 10 (PASS)","godot --headless --path project --script combat_parity_test.gd --quit-after 10 (PASS)","godot --headless --path project --script playable_combat_test.gd --quit-after 10 (PASS; failures=0)","godot --headless --path project --script test_combat_status_effect_parity.gd --quit-after 10 (PASS)","godot --headless --path project --script netplay_test.gd --quit-after 10 (PASS)"],"reason":"按 40250 WeaponTrace::SetWeaponInstance/Update、InstanceBaseEffect::__Warrior_SetGeomgyeongAffect 和 ActorInstanceCollisionDetection::__NormalAttackProcess 修复 bound-box 长度、局部 Z 端点、Geomgyeong 1.5/1.0 reach scale 及普通攻击扫掠位移缩放;当前端仍未直接消费 native bone composite matrix,远端/怪物覆盖、真实视觉资源和服务端包级攻击闭环保持 PARTIAL。"}
{"time":"2026-09-21T04:00:00Z","event":"audit_evidence_reconciliation","result":"PARTIAL","ids":["combat.attack_combo_damage"],"files":["project/weapon_attach_test.gd","audit/contracts/combat.attack-combo-damage.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script weapon_attach_test.gd --quit-after 10 (PASS; 00010.gr2 and 03150.gr2 loaded, exit 0)"],"reason":"重新运行当前工作树的 weapon_attach_test,确认此前 race 0 / 03150 左手贴合失败记录已过期并从待办移除;WeaponTrace native bone composite matrix、远端/怪物覆盖、真实视觉资源和服务端攻击闭环仍未证明。"}
{"time":"2026-09-21T04:00:23Z","event":"implementation_fix_round","result":"PARTIAL","ids":["combat.death.exp_drop"],"files":["project/net_world.gd","project/test_exp_fly_parity.gd","audit/contracts/combat.death-exp-drop.md","audit/manifest.json","audit/history.jsonl"],"tests":["project/test_exp_fly_parity.gd pre-fix: local main EntityStore row removed and _on_fly emitted no projectile","godot --headless --path project --script test_exp_fly_parity.gd --quit-after 10 (PASS; 6/6; 3 ObjectDB leak warnings)","godot --headless --path project --script fly_reset_test.gd --quit-after 10 (PASS)","godot --headless --path project --script netbridge_test.gd --quit-after 10 (PASS)","godot --headless --path project --script test_combat_death_pickup_entry_parity.gd --quit-after 10 (PASS)","godot --headless --path project --script mob_death_drop_test.gd --quit-after 10 (PASS)","godot --headless --path project --script gamescene_test.gd --quit-after 10 (PASS; expected missing-map fixture warning)"],"reason":"按 40250 RecvCreateFlyPacket 的主角实例解析修复 NetWorld:本地主角 EntityStore 行暂缺时,_entity_pos/_on_fly 回退到 _local_node,经验飞行不再因终点 Vector3.INF 被丢弃;真实服务端包序、重复/乱序/重连/拾取竞争和完整跨图清理保持 PARTIAL。"}
{"time":"2026-09-21T04:02:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["combat.death.exp_drop"],"files":["project/net_world.gd","project/test_exp_fly_parity.gd","audit/contracts/combat.death-exp-drop.md","audit/manifest.json","audit/history.jsonl"],"tests":["project/test_exp_fly_parity.gd pre-fix: missing remote endpoint and missing remote start node each incorrectly created a projectile from EntityStore coordinates","godot --headless --path project --script test_exp_fly_parity.gd --quit-after 10 (PASS; local fallback and remote actor gate)","godot --headless --path project --script fly_reset_test.gd --quit-after 10 (PASS)","godot --headless --path project --script netbridge_test.gd --quit-after 10 (PASS)","godot --headless --path project --script test_combat_death_pickup_entry_parity.gd --quit-after 10 (PASS)","godot --headless --path project --script mob_death_drop_test.gd --quit-after 10 (PASS)","godot --headless --path project --script gamescene_test.gd --quit-after 10 (PASS; expected missing-map fixture warning)","godot --headless --path project --script combat_fx_test.gd --quit-after 10 (PASS)"],"reason":"按 40250 RecvCreateFlyPacket 的 GetInstancePtr(startVID/endVID) 门修复 NetWorld:远端任一起点/终点节点缺失时不再仅凭 EntityStore 坐标创建 indexed fly;本地主角继续使用真实 _local_node 回退。真实服务端包序、重复/乱序/重连/拾取竞争和完整跨图清理保持 PARTIAL。"}
{"time":"2026-09-21T04:13:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["item.inventory_equipment_state","item.consumable_action"],"files":["extension/src/net/item_action_rules.h","extension/src/net/m2_client.cpp","extension/src/net/m2_client.h","extension/tests/net_bounds_test.cpp","project/game_scene.gd","project/item_action_sound_parity_test.gd","audit/contracts/item.inventory-equipment-state.md","audit/contracts/item.consumable-action.md","audit/manifest.json","audit/history.jsonl"],"tests":["project/item_action_sound_parity_test.gd pre-fix: item_action_sound signal and item_proto sound classifier were absent (2 failures)","./build-debug/extension/net_bounds_test (PASS)","godot --headless --path project --script item_action_sound_parity_test.gd --quit-after 10 (PASS; one fixture ObjectDB warning)","godot --headless --path project --script inventory_ui_test.gd --quit-after 10 (PASS)","godot --headless --path project --script equip_model_test.gd --quit-after 10 (PASS)","godot --headless --path project --script item_tooltip_test.gd --quit-after 10 (PASS)","godot --headless --path project --script view_equipment_ui_test.gd --quit-after 10 (PASS; 5 ObjectDB instances leaked)","godot --headless --path project --script netbridge_test.gd --quit-after 10 (PASS; 5 ObjectDB instances leaked)"],"reason":"按 40250 CPythonItem::__GetUseSoundType/__GetDropSoundType 与 SendItemUsePacket/SendItemMovePacket 的顺序,将 item_proto type/subtype 音效分类下沉到共享 native 规则;M2Client 在行动门通过后、transport 发包前发出 item_action_soundGameScene 统一交给 Audio。完整 SendSequence/m2dev 包序、服务端拒绝回滚、扩展槽位乱序和换图/断线重建保持 PARTIAL。"}
{"time":"2026-09-21T04:20:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["lifecycle.bootstrap_phase_host"],"files":["project/app_flow.gd","project/login.gd","project/app_flow_lifecycle_test.gd","audit/contracts/lifecycle.bootstrap-phase-host.md","audit/manifest.json","audit/history.jsonl"],"tests":["project/app_flow_lifecycle_test.gd pre-fix: close_requested had no consumer (1 failure)","godot --headless --path project --script app_flow_lifecycle_test.gd --quit-after 10 (PASS)","godot --headless --path project --editor --quit (script load check completed)"],"reason":"按 40250 WM_CLOSE -> CPythonApplication::Destroy 的 owner 顺序修复两条 Godot 启动入口:AppFlow 与旧 login.gd 均消费 close_requested,幂等断开 M2Client、解绑音频/生命周期、释放 GameScene 后退出。真实 socket close 回调、Windows 退出确认和最终 native manager 销毁保持 PARTIAL。"}
{"time":"2026-09-21T04:25:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["lifecycle.bootstrap_phase_host"],"files":["project/app_flow.gd","project/app_flow_lifecycle_test.gd","audit/contracts/lifecycle.bootstrap-phase-host.md","audit/manifest.json","audit/history.jsonl"],"tests":["project/app_flow_lifecycle_test.gd pre-fix: _goto_game contained a direct client.net_poll() call (1 failure)","godot --headless --path project --script app_flow_lifecycle_test.gd --quit-after 10 (PASS)","godot --headless --path project --script gamescene_test.gd --quit-after 10 (PASS; expected missing-map fixture warning)","godot --headless --path project --script net_world_reset_test.gd --quit-after 10 (PASS)"],"reason":"按 40250 CPythonApplication::Process 的单一网络处理 owner 删除 AppFlow::_goto_game 等待模型时的主动 net_poll;改为同步视图并让出帧,避免与 M2Client._process 产生同帧双 pump。GameScene 内部资源加载 pump 和完整运行时 phase/reentry 矩阵仍保持 PARTIAL。"}
{"time":"2026-09-21T04:35:00Z","event":"audit_evidence_reconciliation","result":"PARTIAL","ids":["movement.click_collision"],"files":["audit/contracts/movement.click-collision.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script player_move_test.gd --quit-after 10 (PASS)","godot --headless --path project --script movement_parity_test.gd --quit-after 10 (PASS)","godot --headless --path project --script netplay_test.gd --quit-after 10 (PASS)","godot --headless --path project --script test_click_target_effect_parity.gd --quit-after 10 (PASS; 3 ObjectDB leaks and 1 resource-in-use warning)"],"reason":"继续对照 40250 ActorInstanceCollisionDetection/MapOutdoor picking,确认当前固定半径、单次切线/xz 分轴推进和 800m 高度采样仍不是真实 MSM sphere/object picking 的同一算法;当前 fixture 回归通过但没有新增可安全闭合差异,合同保持 PARTIAL。"}
{"time":"2026-09-21T04:45:00Z","event":"audit_evidence_reconciliation","result":"PARTIAL","ids":["movement.keyboard_motion"],"files":["audit/contracts/movement.keyboard-motion.md","audit/history.jsonl"],"tests":["godot --headless --path project --script keyboard_motion_timeline_test.gd --quit-after 10 (PASS)","godot --headless --path project --script test_wasd_steering_parity.gd --quit-after 10 (PASS)","godot --headless --path project --script test_no_auto_move_regression.gd --quit-after 10 (PASS)","godot --headless --path project --script player_motion_test.gd --quit-after 10 (PASS)"],"reason":"复核 40250 NEW_SetMultiDirKeyState/NEW_MoveToDirection/AccumulationMovement 与当前键盘控制:输入、W/S 切换、停止、自动移动和动作装配回归通过,但 Godot 连续速度预测仍未等价于 .msa 根运动与 OnMove/OnWaiting 事件源,合同保持 PARTIAL。"}
{"time":"2026-09-21T04:23:11Z","event":"audit_evidence_reconciliation","result":"PARTIAL","ids":["movement.remote_sync_state","network.character_select.create_delete","network.packet_dispatch_protocol"],"files":["audit/contracts/movement.remote-sync-state.md","audit/contracts/network.character-select.md","audit/contracts/network.packet-dispatch.md","audit/manifest.json","audit/history.jsonl"],"tests":[".agents/skills/metin2-40250-parity-audit/scripts/audit_packet_registry.py (PARTIAL: 117/117 numeric coverage; extra independent HDR_GC_SYMBOL_DATA=133)",".agents/skills/metin2-40250-parity-audit/scripts/audit_phase_dispatch.py (PASS: Login/Select/Loading/Game payload case sets)",".agents/skills/metin2-40250-parity-audit/scripts/audit_sequence_table.py (PASS: 32768-byte table identical)",".agents/skills/metin2-40250-parity-audit/scripts/audit_source_coverage.py (PASS: 0 unowned behavior candidates)"],"reason":"继续对照远端移动同步、角色选择/DirectEnter 和 classic 包分派:现有主链与结构审计结果稳定,没有发现可在缺少真实动作/地图/locale/服务端包序证据时安全改写的新实现差异;远端真实根运动/纠偏资源、角色异常与编码语义、逐项 wire layout/动态边界/burst 副作用仍保持 PARTIAL。"}
{"time":"2026-09-21T04:29:58Z","event":"implementation_fix_round","result":"PARTIAL","ids":["movement.remote_sync_state"],"files":["extension/src/net/entity_store.cpp","extension/tests/net_state_queue_test.cpp","audit/contracts/movement.remote-sync-state.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix net_state_queue_test: remote NPC/MOB FUNC_MOVE stopped at Dst and failed the reference arrival assertion","cmake --build build-debug --target net_state_queue_test net_entity_test net_classic_session_test -j4 (PASS)","build-debug/extension/net_state_queue_test (PASS)","build-debug/extension/net_entity_test (PASS)","build-debug/extension/net_classic_session_test (PASS)","git diff --check (PASS)"],"reason":"按 40250 CInstanceBase::MovementProcess 的统一远端分支,移除 ch_type 对 FUNC_MOVE 穿越 Dst 行为的错误分叉;NPC/MOB 与 PC 一样继续根运动,只有后续状态或 >100cm overshoot 防呆才停止,攻击/技能/表情到达动作保持原有释放。"}
{"time":"2026-09-21T04:29:58Z","event":"implementation_fix_round","result":"PARTIAL","ids":["quest.quest_event_navigation"],"files":["extension/src/net/entity_store.cpp","extension/tests/net_entity_test.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/quest.quest-event-navigation.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix net_entity_test: QUEST_SEND_IS_BEGIN with isBegin=0 left quest 7 in EntityStore","cmake --build build-debug --target net_entity_test net_classic_session_test -j4 (PASS)","build-debug/extension/net_entity_test (PASS)","build-debug/extension/net_classic_session_test (PASS)","git diff --check (PASS)"],"reason":"按 40250 RecvQuestInfoPacket -> CPythonQuest::DeleteQuestInstance 的 END 分支,EntityStore 的 classic mutator 和协议兼容 apply 路径现在删除结束任务并发出一次列表刷新事件;BEGIN/UPDATE 时间戳、索引顺序、script-button/DONE/ESC 和真实 UI 生命周期仍保持 PARTIAL。"}
{"time":"2026-09-21T04:34:38Z","event":"implementation_fix_round","result":"PARTIAL","ids":["quest.quest_event_navigation"],"files":["extension/src/net/net_bounds.h","extension/src/net/m2_client.cpp","extension/tests/net_bounds_test.cpp","audit/contracts/quest.quest-event-navigation.md","audit/manifest.json","audit/history.jsonl"],"tests":["net_bounds_test: ordinary uint32 script-button values, INT32_MIN..INT32_MIN+0xffff quest sentinels and out-of-range negatives (PASS)","git diff --check (PASS)"],"reason":"按 40250 QuestButtonClick 的 INT32_MIN + questIndex 与 SendScriptButtonPacket(unsigned int) 语义,允许任务日志 sentinel 进入 uint32 wire 字段,同时继续拒绝其他负数;DONE/ESC、任务时钟、索引顺序和 Atlas/cinema 生命周期仍保持 PARTIAL。"}
{"time":"2026-09-21T04:39:21Z","event":"implementation_fix_round","result":"PARTIAL","ids":["quest.quest_event_navigation"],"files":["project/ui/quest_dialog.gd","project/quest_test.gd","project/test_quest_dialog_parity.gd","audit/contracts/quest.quest-event-navigation.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix test_quest_dialog_parity.gd: revised 40250 DONE expectation failed because DoneEvent was delayed and script_answer(254) was sent","godot --headless --path project --script test_quest_dialog_parity.gd --quit-after 10 (PASS; 45 checks)","godot --headless --path project --script quest_test.gd --quit-after 10 (PASS)","git diff --check (PASS)"],"reason":"按 40250 PythonEventManager::ProcessEventSet(EVENT_TYPE_DONE) 与 uiquest.py::MakeNextButton(BUTTON_TYPE_DONE),在处理 DONE token 时发 DoneEventDONE 按钮只关闭对话而不发送 SCRIPT_ANSWER(254)ESC 分支、任务计时、RUN_CINEMA/Atlas 生命周期仍保持 PARTIAL。"}
{"time":"2026-09-21T04:39:21Z","event":"implementation_fix_round","result":"PARTIAL","ids":["quest.quest_event_navigation"],"files":["project/ui/quest_dialog.gd","project/quest_test.gd","project/test_quest_dialog_parity.gd","project/quest_event_test.gd","audit/contracts/quest.quest-event-navigation.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix test_quest_dialog_parity.gd: QUESTION ESC and CONFIRM_WAIT cancel failed the 40250 answer-branch assertions","godot --headless --path project --script test_quest_dialog_parity.gd --quit-after 10 (PASS; 47 checks)","godot --headless --path project --script quest_test.gd --quit-after 10 (PASS)","godot --headless --path project --script quest_event_test.gd --quit-after 10 (PASS)","git diff --check (PASS)"],"reason":"按 40250 uiquest.py::OnPressEscapeKey 与 MakeNextButton(BUTTON_TYPE_CANCEL)QUESTION ESC 发送最后选项,NEXT/CANCEL 发送 254DONE 只关闭,CONFIRM_WAIT 取消不再调用 255 cancel sentinel;任务时钟、真实 server 序列、RUN_CINEMA/Atlas 和断线清理仍保持 PARTIAL。"}
{"time":"2026-09-21T05:02:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["quest.quest_event_navigation"],"files":["extension/src/net/entity_store.h","extension/src/net/entity_store.cpp","extension/tests/net_entity_test.cpp","audit/contracts/quest.quest-event-navigation.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix net_entity_test: quest insertion/update/BEGIN-replacement order assertions failed against unordered_map enumeration","cmake --build build-debug --target net_entity_test net_classic_session_test net_bounds_test -j4 (PASS)","build-debug/extension/net_entity_test (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_bounds_test (PASS)","git diff --check (PASS)"],"reason":"按 40250 CPythonQuest vector 语义增加 m_quest_order;普通 UPDATE 保持任务位置,未知 UPDATE 追加,BEGIN 删除旧实例并追加新实例,END 删除对应顺序项。任务 start timestamp、真实 UI 行号映射、RUN_CINEMA/Atlas 生命周期和断线清理仍保持 PARTIAL。"}
{"time":"2026-09-21T05:07:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["quest.quest_event_navigation"],"files":["extension/src/net/entity_store.cpp","extension/tests/net_entity_test.cpp","audit/contracts/quest.quest-event-navigation.md","audit/history.jsonl"],"tests":["pre-fix net_entity_test: classic-style quest UPDATE changed the active instance begin flag to false","cmake --build build-debug --target net_entity_test net_classic_session_test -j4 (PASS)","build-debug/extension/net_entity_test (PASS)","build-debug/extension/net_classic_session_test (PASS)","git diff --check (PASS)"],"reason":"按 40250 RecvQuestInfoPacket UPDATE 只更新已有实例字段、只有 END 删除实例的语义,classic mut_quest_info 现在保持所有非 END QuestInfo 为 active;任务 start timestamp、真实 UI 行号映射、RUN_CINEMA/Atlas 生命周期和断线清理仍保持 PARTIAL。"}
{"time":"2026-09-21T05:22:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["quest.quest_event_navigation"],"files":["extension/src/net/entity_store.h","extension/src/net/entity_store.cpp","extension/src/net/m2_client.cpp","extension/tests/net_entity_test.cpp","project/ui/quest_log.gd","project/ui/char_status_ui.gd","project/quest_test.gd","project/test_quest_hud_parity.gd","audit/contracts/quest.quest-event-navigation.md","audit/manifest.json","audit/history.jsonl"],"tests":["cmake --build build-debug --target net_entity_test net_classic_session_test mtgodot -j4 (PASS)","build-debug/extension/net_entity_test (PASS)","build-debug/extension/net_classic_session_test (PASS)","godot --headless --path project --script quest_test.gd --quit-after 10 (PASS)","godot --headless --path project --script test_quest_hud_parity.gd --quit-after 10 (PASS; 19 checks)","git diff --check (PASS)"],"reason":"按 40250 CPythonQuest::RegisterQuestInstance/MakeQuest/SetQuestClockValue/GetQuestLastTime 增加 clock_start_msBEGIN、未知 UPDATE 和 clock_value UPDATE 重置起点,普通 UPDATE 保持起点;QuestLog 与 CharStatusUI 按起点计算剩余时间,关闭后重开不恢复初始值。精确 CTimer 时间基准、后台恢复、过期清理和真实服务端序列仍保持 PARTIAL。"}
{"time":"2026-09-21T05:35:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["quest.quest_event_navigation"],"files":["project/ui/atlas_ui.gd","project/game_scene.gd","project/atlas_test.gd","audit/contracts/quest.quest-event-navigation.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script atlas_test.gd --quit-after 10 (PASS)","godot --headless --path project --script test_atlas_navigation_parity.gd --quit-after 10 (PASS; 23 checks)","godot --headless --path project --script quest_event_test.gd --quit-after 10 (PASS)","git diff --check (PASS)"],"reason":"按 40250 EVENT_TYPE_ADD_MAP_SIGNAL 同时调用 CPythonMiniMap::AddSignalPoint 与 AddWayPoint(TYPE_WAYPOINT)GameScene 现在将任务坐标同时写入 Minimap/AtlasUIAtlas overlay 采用同一坐标转换绘制 waypointCLEARMAPSIGNAL 同步清理。真实 Atlas 资源、切图/多点生命周期、RUN_CINEMA 资源序列和中断清理仍保持 PARTIAL。"}
{"time":"2026-09-21T05:48:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["quest.quest_event_navigation"],"files":["project/ui/quest_dialog.gd","project/test_quest_dialog_parity.gd","audit/contracts/quest.quest-event-navigation.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix behavior: missing RUN_CINEMA opened an empty locked dialog","godot --headless --path project --script test_quest_dialog_parity.gd --quit-after 10 (PASS; 49 checks)","git diff --check (PASS)"],"reason":"按 40250 RegisterEventSetFromString/RecvScriptPacket 的 -1 失败分支,RUN_CINEMA 指向不存在或空路径时现在清理临时 event set、保持任务窗口关闭且不发出 opened;有效 .msc 的完整事件序列、过场消费者和中断清理仍保持 PARTIAL。"}
{"time":"2026-09-21T06:12:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["ui.equipment.tooltip"],"files":["project/ui/item_tooltip_bridge.gd","project/ui/exchange_ui.gd","project/ui/safebox_ui.gd","project/ui/mall_ui.gd","project/ui/private_shop_ui.gd","project/test_safebox_mall_parity.gd","audit/contracts/ui.equipment-tooltip.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script test_safebox_mall_parity.gd --quit-after 10 (PASS; 40 checks)","godot --headless --path project --script p8_test.gd --quit-after 10 (PASS)","godot --headless --path project --script test_npc_shop_flow.gd --quit-after 10 (PASS; 41 checks)","godot --headless --path project --script private_shop_ui_test.gd --quit-after 10 (PASS)","godot --headless --path project --script item_tooltip_test.gd --quit-after 10 (PASS)","git diff --check (PASS)"],"reason":"按 40250 ItemToolTip 单实例生命周期新增 ItemTooltipBridge,交易/仓库/商城仓库/个人摊位的 item rows/slots 清除原生 tooltip_text 并切换共享自绘 ItemTooltipView;关闭路径主动隐藏。真实运行时 UiManager 跨窗口共享、边界定位、快速切换和完整销毁顺序仍保持 PARTIAL。"}
{"time":"2026-09-21T05:18:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["skill.cast-effect-timing"],"files":["project/net_play.gd","project/game_scene.gd","project/test_combat_death_pickup_entry_parity.gd","audit/contracts/skill.cast-effect-timing.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script test_combat_death_pickup_entry_parity.gd --quit-after 20 (PASS; motion-driven lock regression)","godot --headless --path project --script combat_parity_test.gd --quit-after 20 (PASS)","godot --headless --path project --script target_effect_test.gd --quit-after 20 (PASS)","godot --headless --path project --script test_no_auto_move_regression.gd --quit-after 20 (PASS)","godot --headless --path project --script netplay_test.gd --quit-after 20 (PASS)","godot --headless --path project --script skill_test.gd --quit-after 20 (PASS)","godot --headless --path project --script combat_fx_test.gd --quit-after 20 (PASS)","godot --headless --path project --script effect_playback_test.gd --quit-after 20 (PASS)","godot --headless --path project --script test_skill_state_arg_parity.gd --quit-after 20 (PASS)","godot --headless --path project --script net_world_remote_action_test.gd --quit-after 20 (PASS)","godot --headless --path project --script player_motion_test.gd --quit-after 20 (PASS)","git diff --check (PASS)"],"reason":"按 40250 ActorInstanceMotionEvent/NEW_UseSkill 的动作所有权语义,真实 MSA 绑定的技能施法锁定现在由 PlayerView 的 motion_bound(\"wait\") 动作尾释放,固定 duration 仅保留给缺失 MSA/headless 兼容路径;死亡、重置和网络状态失效会清理 motion-driven 门。逐技能 MSA→MSE 挂点、颜色/混合、飞行/特殊攻击、服务端结果和完整中断清理仍保持 PARTIAL。"}
{"time":"2026-09-21T05:25:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["movement.motion_resource_events"],"files":["extension/src/metin2_anim.cpp","project/motion_event_payload_test.gd","project/animation_cache_test.gd","audit/contracts/movement.motion-resource-events.md","audit/manifest.json","audit/history.jsonl"],"tests":["cmake --build build-debug --target mtgodot -j4 (PASS)","godot --headless --path project --script motion_event_payload_test.gd --quit-after 30 (PASS)","godot --headless --path project --script skill_motion_loop_test.gd --quit-after 30 (PASS)","godot --headless --path project --script player_motion_test.gd --quit-after 20 (PASS)","godot --headless --path project --script combat_fx_test.gd --quit-after 20 (PASS)","godot --headless --path project --script keyboard_motion_timeline_test.gd --quit-after 20 (PASS)","godot --headless --path project --script animation_cache_test.gd --quit-after 30 (PASS; hits=17/misses=3, msa_hits=17/msa_misses=3)","git diff --check (PASS)"],"reason":"按 40250 CRaceMotionData::GetMotionDuration 的资源来源,Metin2AnimPlayer 对 .msa 使用 MotionDuration 作为动作/LoopData/事件时序权威,raw .gr2 或缺失时长才回退 GR2;同时将缓存回归改为真正的已注册动作热切换,确认 decoded clip 与 MSA metadata 复用。完整 RaceData motion key/权重/父模式、所有 actor 事件消费、动作队列和清理仍保持 PARTIAL。"}
{"time":"2026-09-21T05:37:21Z","event":"implementation_fix_round","result":"PARTIAL","ids":["movement.motion_resource_events"],"files":["project/ui/motion_registry.gd","project/ui/player_view.gd","project/ui/hit_reaction.gd","project/player_motion_test.gd","project/hit_view_test.gd","project/race_motion_assembly_test.gd","project/motion_registry_test.gd","audit/contracts/movement.motion-resource-events.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script motion_registry_test.gd --quit-after 20 (PASS)","godot --headless --path project --script player_motion_test.gd --quit-after 30 (PASS)","godot --headless --path project --script hit_view_test.gd --quit-after 30 (PASS)","godot --headless --path project --script race_motion_assembly_test.gd --quit-after 40 (PASS; 8 races)","godot --headless --path project --script combat_fx_test.gd --quit-after 25 (PASS)","godot --headless --path project --script keyboard_motion_timeline_test.gd --quit-after 20 (PASS)","git diff --check (PASS)"],"reason":"按 40250 playersettingmodule.py→CRaceData::RegisterMotionData→CActorInstance::GetRandomMotionKey,新增资源驱动的 PC motion registry,复刻注册顺序、重复项、默认权重、SetMotionRandomWeight 和 random()%100;补齐 HORSE_*→HORSE 父模式查找。按 ActorInstanceBattle.cpp::__HitGood/__HitGreate 记录受击链当前步骤,修正击倒/起身期间错误插入 DAMAGE 的早退分支。PC 权重/父模式/受击链回归通过,NPC 全量 motlist、完整 RaceData 失败语义、所有 actor 事件消费者和队列清理仍保持 PARTIAL。"}
{"time":"2026-09-21T05:39:51Z","event":"test_run","result":"PASS","ids":["movement.motion_resource_events"],"files":["project/animation_cache_test.gd","project/motion_registry_test.gd","audit/contracts/movement.motion-resource-events.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script animation_cache_test.gd --quit-after 30 (PASS; hits=16/misses=4, msa_hits=16/msa_misses=4; expected weighted wait variants)","godot --headless --path project --script motion_registry_test.gd --quit-after 20 (PASS)","git diff --check (PASS)"],"reason":"加权 wait 资源可能使两个 actor 初始绑定不同的注册变体;缓存回归改为按本次实际唯一资源集合计算 misses,继续验证所有热切换命中 decoded clip/MSA metadata 缓存。"}
{"time":"2026-09-21T05:44:18Z","event":"implementation_fix_round","result":"PARTIAL","ids":["movement.motion_resource_events"],"files":["project/ui/player_view.gd","project/player_motion_test.gd","project/race_motion_assembly_test.gd","project/hit_view_test.gd","audit/contracts/movement.motion-resource-events.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script motion_registry_test.gd --quit-after 20 (PASS)","godot --headless --path project --script player_motion_test.gd --quit-after 30 (PASS; HORSE unregistered standup does not fall through)","godot --headless --path project --script hit_view_test.gd --quit-after 30 (PASS)","godot --headless --path project --script race_motion_assembly_test.gd --quit-after 40 (PASS; 8 races)","godot --headless --path project --script animation_cache_test.gd --quit-after 30 (PASS; weighted variants)","godot --headless --path project --script combat_fx_test.gd --quit-after 25 (PASS)","git diff --check (PASS)"],"reason":"进一步按 CRaceData::GetMotionKey 收紧 mode/index 分支:普通模式缺 key 只回 GENERALHORSE_* 只回 HORSE,父模式也缺失时不再用 GENERAL 伪造动作;SetLoopMotion/InterceptMotion 的缺失 key 现在保持当前动画状态。同步修正了随机动作测试和缺失技能夹具,相关回归通过;NPC motlist、全量 RaceData 失败语义、所有 actor 事件消费者和队列清理仍保持 PARTIAL。"}
{"time":"2026-09-21T05:55:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["movement.motion_resource_events"],"files":["project/ui/mob_view.gd","project/mob_view_test.gd","formats/msm.h","formats/msm.cpp","formats/tests/msm_test.cpp","audit/contracts/movement.motion-resource-events.md","audit/manifest.json","audit/history.jsonl"],"tests":["godot --headless --path project --script mob_view_test.gd (PASS)","godot --headless --path project --script motion_registry_test.gd (PASS)","godot --headless --path project --script player_motion_test.gd (PASS)","godot --headless --path project --script hit_view_test.gd (PASS)","godot --headless --path project --script keyboard_motion_timeline_test.gd (PASS)","godot --headless --path project --script race_motion_assembly_test.gd (PASS; 8 races)","godot --headless --path project --script animation_blend_test.gd (PASS; 8 races)","godot --headless --path project --script animation_cache_test.gd (PASS; hits=17/misses=3, msa_hits=17/msa_misses=3)","godot --headless --path project --script test_combo_continuous_flow.gd (PASS)","godot --headless --path project --script combat_fx_test.gd (PASS)","cmake --build build --target formats_msm_test -j2 (PASS)","ctest --test-dir build --output-on-failure -R formats\\.msm_hair|formats\\.msa_loop_data|formats\\.combo_table (PASS; 3/3)","git diff --check (PASS)"],"reason":"按 RaceDataFile.cpp / RaceManager::__LoadRaceMotionList 补齐 NPC motlist 资源链:解析 .msm MotionListFileName,按 40250 EName 索引归并 alias、保留注册顺序与百分比权重、复刻最多两字符后缀识别和缺 SPAWN 的 DAMAGE fallback;动作 key 缺失时不再跨 WALK/RUN 或 DAMAGE/WAIT 伪造动作。完整 RaceData mode/parent、所有 NPC 技能索引、MotionEvent 消费、动作预约队列和跨 actor 清理仍保持 PARTIAL。"}
{"time":"2026-09-21T06:02:00Z","event":"test_run","result":"PASS","ids":["movement.motion_resource_events"],"files":["formats/msm.h","formats/msm.cpp","project/ui/mob_view.gd","project/mob_view_test.gd"],"tests":["cmake --build build --target mtgodot -j2 (PASS)","ctest --test-dir build --output-on-failure -j1 (PASS; 23/23)","godot --headless --path project --script motion_event_payload_test.gd (PASS)","godot --headless --path project --script skill_motion_loop_test.gd (PASS)","godot --headless --path project --script net_world_remote_action_test.gd (PASS)","godot --headless --path project --script mob_view_test.gd (PASS)","godot --headless --path project --script motion_registry_test.gd (PASS)","git diff --check (PASS)"],"reason":"NPC motlist/MSM 修改完成原生扩展重编译;全量 CTest 23/23 与动作事件、技能 LoopData、远端动作和 NPC 注册表回归通过。完整 RaceData/所有 actor 事件消费者与动作队列仍保持 PARTIAL。"}
{"time":"2026-09-21T06:15:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["movement.motion_resource_events"],"files":["extension/src/metin2_anim.cpp","extension/src/metin2_anim.h","project/motion_event_timing_test.gd","audit/contracts/movement.motion-resource-events.md","audit/manifest.json","audit/history.jsonl"],"tests":["cmake --build build-debug --target mtgodot -j2 (PASS)","godot --headless --path project --script motion_event_timing_test.gd (PASS)","godot --headless --path project --script motion_event_payload_test.gd (PASS)","godot --headless --path project --script skill_motion_loop_test.gd (PASS)","godot --headless --path project --script animation_cache_test.gd (PASS; hits=17/misses=3)","godot --headless --path project --script player_motion_test.gd (PASS)","godot --headless --path project --script hit_view_test.gd (PASS)","godot --headless --path project --script combat_fx_test.gd (PASS)","git diff --check (PASS)"],"reason":"按 ActorInstanceMotion.cpp::__MotionEventProcess 修正 frame-0 事件、LoopData 回绕起点和跨多个完整周期的大 delta 事件派发;首帧事件不再漏发,连续帧不重复,循环事件按每个 duration 分段处理。60 FPS 离散帧、所有 LoopData 资源变体、非主角事件消费者和动作队列仍保持 PARTIAL。"}
{"time":"2026-09-21T06:20:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["movement.motion_resource_events"],"files":["project/ui/player_view.gd","project/ui/mob_view.gd","project/player_motion_test.gd","audit/contracts/movement.motion-resource-events.md","audit/history.jsonl"],"tests":["godot --headless --path project --script player_motion_test.gd (PASS)","godot --headless --path project --script mob_view_test.gd (PASS)","git diff --check (PASS)"],"reason":"按 ActorInstanceMotion.cpp::__SetMotion 的隐藏状态恢复语义,成功解析并绑定新动作前执行 __ShowEvent;当前 PlayerView/MobView 对 CHARACTER_HIDE 后的同状态和新状态动作请求都会恢复可见性,缺失动作仍保留隐藏状态。type 4 splash、type 6 fly 资源消费、所有 actor 事件消费者和动作队列清理仍保持 PARTIAL。"}
{"time":"2026-09-21T06:30:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["movement.motion_resource_events","combat.flying_projectile"],"files":["project/ui/player_view.gd","project/net_world.gd","project/game_scene.gd","project/motion_event_fly_test.gd","audit/contracts/movement.motion-resource-events.md","audit/history.jsonl"],"tests":["godot --headless --path project --script motion_event_fly_test.gd (PASS)","godot --headless --path project --script motion_event_visibility_test.gd (PASS)","godot --headless --path project --script fly_test.gd (PASS)","git diff --check (PASS)"],"reason":"按 40250 ProcessMotionEventFly/FlyingObjectManager::CreateFlyingInstanceFlyTarget 补齐本地主角 type 6:有效 .msf 资源进入 FlyManager、动作骨骼起点使用同一坐标变换,CG_SHOOT 仍由 queued uSkill 单独发送;GC_CREATE_FLY 索引弹道保持独立,避免重复。远端资源化 type 6、完整 FlyTrace/AttachData、type 4 全 actor 消费和事件清理仍保持 PARTIAL。"}
{"time":"2026-09-21T06:40:00Z","event":"test_run","result":"PARTIAL","ids":["movement.motion_resource_events","combat.flying_projectile"],"files":["project/ui/player_view.gd","project/net_world.gd","project/game_scene.gd","project/motion_event_fly_test.gd"],"tests":["motion_event_fly_test.gd (PASS)","motion_event_visibility_test.gd (PASS)","motion_event_timing_test.gd (PASS)","motion_event_payload_test.gd (PASS)","fly_test.gd (PASS)","skill_motion_loop_test.gd (PASS)","animation_cache_test.gd (PASS; hits=17/misses=3, msa_hits=17/msa_misses=3)","player_motion_test.gd (intermittent failure: weighted HORSE WAIT assertion)","hit_view_test.gd (PASS)","mob_view_test.gd (PASS)","net_world_motion_event_test.gd (PASS)","net_world_remote_action_test.gd (PASS)","combat_fx_test.gd (PASS)","cmake --build build-debug --target mtgodot -j2 (PASS)","ctest --test-dir build-debug --output-on-failure -j1 (PASS; 23/23)","audit_ledger.py validate (PASS)","git diff --check (PASS)"],"reason":"联合回归暴露了测试将 40250 加权 HORSE WAIT 的随机结果写死为 wait.msa;该测试断言随后修正为接受 wait、wait_1、wait_2 合法注册变体。"}
{"time":"2026-09-21T06:24:48Z","event":"audit_round","result":"PARTIAL","ids":["combat.flying_projectile"],"files":["project/net_world.gd","project/fly_object.gd","audit/contracts/combat.flying-projectile.md","audit/history.jsonl"],"tests":["audit_ledger.py refresh --write (PASS; 0 changes before this audit entry)","audit_ledger.py validate (PASS; 45 contracts)","40250 FlyingObjectManager/FlyingInstance/FlyTarget/ActorInstanceFly static source comparison (PASS)"],"reason":"源码级确认 indexed fly 的 FIRE_CRACKER/AUTO_FIRE 类型分支、动态 collision sphere + HittedObjectSet、Actor 销毁即时 NotifyTargetClear、包围球目标位置和 EffectManager/FlyTrace 资源消费仍未与当前端统一;16 个索引路径本身已存在,但当前 _on_fly 统一走普通目标分支。未修改运行时代码,合同保持 PARTIAL。"}
{"time":"2026-09-21T06:34:07Z","event":"implementation_fix_round","result":"PARTIAL","ids":["combat.flying_projectile"],"files":["project/net_world.gd","project/net_play.gd","project/fly_object.gd","project/indexed_fly_type_test.gd","project/fly_dynamic_collision_test.gd","project/fly_target_lifecycle_test.gd","audit/contracts/combat.flying-projectile.md","audit/history.jsonl"],"tests":["indexed_fly_type_test.gd (PASS; 修复前 FIRE_CRACKER/AUTO_FIRE 断言失败)","fly_dynamic_collision_test.gd (PASS)","fly_target_lifecycle_test.gd (PASS)","fly_test.gd (PASS)","fly_reset_test.gd (PASS)","fly_data_msf_test.gd (PASS)","motion_event_fly_test.gd (PASS)","test_exp_fly_parity.gd (6/6 PASS; existing harness ObjectDB warning)","netbridge_test.gd (PASS)","combat_fx_test.gd (PASS)","netplay_test.gd (PASS)","test_click_target_effect_parity.gd (0 failures; existing harness leak warning)"],"reason":"按 40250 CreateIndexedFly、FlyingInstance::Update、FlyTarget::NotifyTargetClear 和 ActorInstanceFly::OnGetFlyTargetPosition 修复索引类型分支、动态 Actor 碰撞/去重、目标包围球中心和销毁时序。EffectManager/FlyTrace 真实资源表现、模型动态半径标定、包序和不可见 Actor 生命周期仍保持 PARTIAL。"}
{"time":"2026-09-21T06:36:22Z","event":"test_run","result":"PARTIAL","ids":["combat.flying_projectile"],"files":["project/fly_object.gd","project/net_world.gd","project/net_play.gd","audit/contracts/combat.flying-projectile.md","audit/manifest.json","audit/reports/coverage.md"],"tests":["cmake --build build-debug --target mtgodot -j2 (PASS)","ctest --test-dir build-debug --output-on-failure -j1 (PASS; 23/23)","audit_ledger.py report --write (PASS)","audit_ledger.py validate (PASS; 45 contracts)","git diff --check (PASS)"],"reason":"索引类型、动态碰撞和目标生命周期修复后的原生构建、全量 CTest、审计报告和格式检查通过;合同仍为 PARTIAL,因为真实 EffectManager/FlyTrace、模型碰撞半径、包序和不可见 Actor 生命周期尚未闭合。"}
{"time":"2026-09-21T06:46:44Z","event":"implementation_fix_round","result":"PARTIAL","ids":["combat.flying_projectile"],"files":["project/fly_object.gd","project/fx/effect_registry.gd","project/fly_data_msf_test.gd","project/fly_attachment_effect_test.gd","audit/contracts/combat.flying-projectile.md","audit/history.jsonl"],"tests":["fly_data_msf_test.gd (PASS; TailLength 秒单位、TailSize cm→m、AttachData)","fly_attachment_effect_test.gd (PASS; AttachFile、FlyTrace、BombEffect、资源视觉去重、地图清理)"],"reason":"按 40250 FlyingData::LoadScriptFile、FlyTrace 和 FlyingObjectManager 的资源生命周期接入 AttachFile/FlyTrace/BombEffectTailLength 保持秒、TailSize 只转换厘米单位,并修复 EffectRegistry 对绝对 .msf 资源路径的解析。真实相机尾迹、所有资源组合、远端动作事件 owner/skill 链和包序仍保持 PARTIAL。"}
{"time":"2026-09-21T06:47:00Z","event":"test_run","result":"PARTIAL","ids":["combat.flying_projectile"],"files":["project/fly_object.gd","project/fx/effect_registry.gd","project/fly_data_msf_test.gd","project/fly_attachment_effect_test.gd","audit/contracts/combat.flying-projectile.md","audit/manifest.json","audit/reports/coverage.md"],"tests":["fly_attachment_effect_test.gd (PASS)","fly_data_msf_test.gd (PASS)","indexed_fly_type_test.gd (PASS)","fly_dynamic_collision_test.gd (PASS)","fly_target_lifecycle_test.gd (PASS)","fly_test.gd (PASS)","fly_reset_test.gd (PASS)","motion_event_fly_test.gd (PASS)","test_exp_fly_parity.gd (6/6 PASS; legacy fixture warnings remain)","combat_fx_test.gd (PASS)","netplay_test.gd (PASS)","cmake --build build-debug --target mtgodot -j2 (PASS)","ctest --test-dir build-debug --output-on-failure -j1 (PASS; 23/23)","audit_ledger.py refresh --write (PASS)","audit_ledger.py report --write (PASS)","audit_ledger.py validate (PASS; 45 contracts)","git diff --check (PASS)"],"reason":"资源特效、索引类型、动态碰撞、目标生命周期、原生构建、全量 CTest 和审计账本验证通过;合同仍为 PARTIAL,因为远端动作事件/包序、真实资源全矩阵、模型半径和不可见 Actor 生命周期尚未闭合。"}
{"time":"2026-09-21T06:50:12Z","event":"test_run","result":"PARTIAL","ids":["combat.flying_projectile"],"files":["project/netbridge_test.gd","project/fly_object.gd","audit/history.jsonl"],"tests":["netbridge_test.gd (PASS)","cmake --build build-debug --target mtgodot -j2 (PASS)","ctest --test-dir build-debug --output-on-failure -j1 (PASS; 23/23)","audit_ledger.py refresh --write (PASS; 22 changes)","audit_ledger.py report --write (PASS)","audit_ledger.py validate (PASS; 45 contracts)","git diff --check (PASS)"],"reason":"资源视觉加入尾迹后,netbridge 回归从写死“子节点恰好增加 1 个”调整为验证 CreateFly 实例实际创建且资源视觉/尾迹挂载;随后 Godot 网络桥、原生构建、全量 CTest、审计账本和格式检查均通过。合同保持 PARTIAL。"}
{"time":"2026-09-21T06:54:51Z","event":"implementation_fix_round","result":"PARTIAL","ids":["combat.flying_projectile","movement.motion_resource_events"],"files":["project/net_world.gd","project/remote_motion_fly_test.gd","audit/contracts/combat.flying-projectile.md","audit/manifest.json","audit/reports/coverage.md","audit/history.jsonl"],"tests":["remote_motion_fly_test.gd (PASS; 无 ObjectDB 泄漏)"],"reason":"按 40250 CActorInstance::ProcessMotionEventFly 补齐远端 Actor 的 MSA type 6:从 GC_FLY_TARGETING/GC_ADD_FLY_TARGETING 目标队列解析对象或坐标目标,使用远端动作位置/挂骨骼位置创建 .msf 飞行实例,并传递 owner VID 与 skill indexGC_CREATE_FLY 索引路径保持独立。原生 skill 上下文缺少完整网络字段、不可见 Actor、包序和全量资源矩阵仍保持 PARTIAL。"}
{"time":"2026-09-21T06:56:40Z","event":"test_run","result":"PARTIAL","ids":["combat.flying_projectile","movement.motion_resource_events"],"files":["project/net_world.gd","project/remote_motion_fly_test.gd","project/net_world_motion_event_test.gd","audit/contracts/combat.flying-projectile.md","audit/manifest.json","audit/reports/coverage.md"],"tests":["remote_motion_fly_test.gd (PASS)","net_world_motion_event_test.gd (PASS)","motion_event_fly_test.gd (PASS)","netbridge_test.gd (PASS)","indexed_fly_type_test.gd (PASS)","fly_attachment_effect_test.gd (PASS)","fly_data_msf_test.gd (PASS)","fly_dynamic_collision_test.gd (PASS)","fly_target_lifecycle_test.gd (PASS)","fly_reset_test.gd (PASS)","combat_fx_test.gd (PASS)","cmake --build build-debug --target mtgodot -j2 (PASS)","ctest --test-dir build-debug --output-on-failure -j1 (PASS; 23/23)","audit_ledger.py refresh --write (PASS; 21 changes)","audit_ledger.py report --write (PASS)","audit_ledger.py validate (PASS; 45 contracts)","git diff --check (PASS)"],"reason":"远端动作事件飞行、既有本地动作/资源/目标/网络桥回归、原生构建、全量 CTest、审计账本和格式检查全部通过;合同仍为 PARTIAL,因为原生 skill 上下文、不可见 Actor 生命周期、包序和完整资源矩阵尚未闭合。"}
{"time":"2026-09-21T06:59:32Z","event":"implementation_fix_round","result":"PARTIAL","ids":["combat.flying_projectile","network.packet_dispatch_protocol"],"files":["extension/src/net/m2_client.h","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_session.h","extension/src/net/classic/classic_session.cpp","project/net_play.gd","project/netbridge_test.gd","project/combat_fx_test.gd","extension/tests/net_classic_session_test.cpp","audit/contracts/combat.flying-projectile.md","audit/manifest.json","audit/reports/coverage.md","audit/history.jsonl"],"tests":["net_classic_session_test (PASS; CG_FLY_TARGETING/CG_ADD_FLY_TARGETING header + sequence)","combat_fx_test.gd (PASS; bow primary target uses fly_targeting API)"],"reason":"按 40250 OnSetFlyTarget/SendFlyTargetingPacket 与 PythonPlayerSkill 附加目标链拆分主目标和追加目标 API;普通弓箭改发 CG_FLY_TARGETING,扇形/圆形附加目标继续发 CG_ADD_FLY_TARGETINGClassicSession 字节级验证两种 header 和 sequence。真实 socket 乱序、重连包序和不可见 Actor 生命周期仍保持 PARTIAL。"}
{"time":"2026-09-21T07:00:11Z","event":"test_run","result":"PARTIAL","ids":["combat.flying_projectile","network.packet_dispatch_protocol"],"files":["extension/src/net/m2_client.h","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_session.h","extension/src/net/classic/classic_session.cpp","project/net_play.gd","project/combat_fx_test.gd","extension/tests/net_classic_session_test.cpp","audit/contracts/combat.flying-projectile.md","audit/manifest.json","audit/reports/coverage.md"],"tests":["cmake --build build-debug --target mtgodot net_classic_session_test net_classic_stream_test -j2 (PASS)","net_classic_session_test (PASS)","net_classic_stream_test (PASS)","combat_fx_test.gd (PASS)","netbridge_test.gd (PASS)","netplay_test.gd (PASS)","remote_motion_fly_test.gd (PASS)","ctest --test-dir build-debug --output-on-failure -j1 (PASS; 23/23)","audit_ledger.py refresh --write (PASS; 35 changes)","audit_ledger.py report --write (PASS)","audit_ledger.py validate (PASS; 45 contracts)","git diff --check (PASS)"],"reason":"主/附加飞行目标包修复后的编译、字节级 ClassicSession、Godot 战斗/网络桥/远端飞行回归、全量 CTest 和审计账本均通过;合同继续 PARTIAL,因为真实 socket 乱序、重连包序、不可见 Actor、原生 skill 上下文和完整资源矩阵尚未闭合。"}
{"time":"2026-09-21T07:03:56Z","event":"implementation_fix_round","result":"PARTIAL","ids":["combat.flying_projectile"],"files":["project/fly_object.gd","project/fly_attachment_effect_test.gd","audit/contracts/combat.flying-projectile.md","audit/history.jsonl"],"tests":["fly_attachment_effect_test.gd (PASS; MULTI_LINE 负 Z 几何断言、AttachFile、FlyTrace、BombEffect、资源视觉去重)","fly_data_msf_test.gd (PASS)","fly_test.gd (PASS)","fly_dynamic_collision_test.gd (PASS)","fly_target_lifecycle_test.gd (PASS)","fly_reset_test.gd (PASS)"],"reason":"按 40250 FlyingInstance::UpdateAttachInstance 修正 MULTI_LINE/SINE/EXP 的局部 Z 偏移符号,并让 LINE 只使用基础飞行旋转、其他偏移类型叠加 AttachRotation;命中资源不重复绘制的前一轮修复继续通过。cone/roll 初始旋转、相机尾迹顶点、完整资源矩阵、远端原生 skill 上下文和真实包序仍保持 PARTIAL。"}
{"time":"2026-09-21T07:08:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["world.entity_spawn_state_sync"],"files":["project/net_world.gd","project/net_world_respawn_test.gd","audit/contracts/world.entity-spawn-state-sync.md","audit/history.jsonl"],"tests":["net_world_respawn_test.gd (PASS; 普通远端渐隐/同 VID 重建、主角色立即删除)","net_world_reset_test.gd (PASS)","net_world_vis_test.gd (PASS)","fly_target_lifecycle_test.gd (PASS)","netbridge_test.gd (PASS)"],"reason":"按 40250 CNetworkActorManager::__RemoveCharacterManagerActor 区分主 actor 的 DeleteInstance 与普通 actor 的 DeleteInstanceByFade;主 VID 不再进入渐隐队列,普通远端的同 VID 重建和旧 tween 隔离保持不变。主 VID 切换、Delete/map reset 后迟到包和渲染副作用顺序仍保持 PARTIAL。"}
{"time":"2026-09-21T07:15:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["world.entity_spawn_state_sync"],"files":["extension/src/net/classic/classic_parser.h","extension/src/net/classic/classic_parser.cpp","extension/src/net/classic/classic_session.h","extension/src/net/m2_client.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/world.entity-spawn-state-sync.md","audit/history.jsonl"],"tests":["cmake --build build-debug --target mtgodot net_classic_session_test net_entity_test -j2 (PASS)","net_classic_session_test (PASS)","net_entity_test (PASS)"],"reason":"按 40250 RecvCharacterAdditionalInfo 的单个静态 SNetworkActorData 生命周期,Delete 匹配 VID 时清除 pending,新增 ClassicSession::reset_for_map_change() 在 Loading/warp/disconnect 时同步清除 parser 暂存和 EntityStore;迟到 AdditionalInfo 不再复活已删除或旧地图角色。主 VID 切换、跨连接迟到 Update/Move 和渲染副作用顺序仍保持 PARTIAL。"}
{"time":"2026-09-21T07:18:00Z","event":"test_run","result":"PARTIAL","ids":["world.entity_spawn_state_sync","combat.flying_projectile","network.packet_dispatch_protocol"],"files":["audit/manifest.json","audit/reports/coverage.md","audit/reports/source-coverage.md","audit/source-coverage.json","audit/history.jsonl"],"tests":["audit_source_coverage.py --write (PASS; 524 active reference files, 0 unowned candidates)","audit_phase_dispatch.py --strict (PASS)","audit_sequence_table.py (PASS; current/reference table identical, 32768 bytes)","audit_ledger.py refresh --write (PASS; 28 changes)","audit_ledger.py report --write (PASS)","audit_ledger.py validate (PASS; 45 contracts)","ctest --test-dir build-debug --output-on-failure -j1 (PASS; 23/23)","git diff --check (PASS)"],"reason":"迟到 AdditionalInfo、主/远端删除分支和资源/飞行修复后的全量原生回归、协议 dispatch/sequence/source coverage 审计均通过;45 份合同中仍有 44 份 PARTIAL,未将静态覆盖或局部测试误报为完整等价。"}
{"time":"2026-09-21T07:27:34Z","event":"implementation_fix_round","result":"PARTIAL","ids":["ui.input_camera_mobile"],"files":["project/game_camera.gd","project/game_camera_test.gd","audit/contracts/ui.input-camera-mobile.md","audit/history.jsonl"],"tests":["game_camera_test.gd (PASS; 默认值、RESTORE_CAMERA、动态目标高度、滚轮阻尼、键盘 0.05 比例)","input_key_test.gd (PASS; 20 ObjectDB 与 1 个 Camera RID 泄漏警告仍存在)","mobile_gesture_test.gd (PASS)","mobile_ui_test.gd (PASS)","mobile_window_host_test.gd (PASS)"],"reason":"按 40250 CameraProcedure/PythonApplicationCamera/EterLib Camera 的已确认链路,修正默认相机值、目标高度插值、滚轮 0.5 阻尼和 0.05 比例缩放;IME、完整鼠标按钮分派、硬件/连续光标和异常清理仍未闭合。"}
{"time":"2026-09-21T07:41:14Z","event":"implementation_fix_round","result":"PARTIAL","ids":["skill.cast.effect_timing"],"files":["project/net_play.gd","project/net_world.gd","project/game_scene.gd","project/remote_motion_splash_test.gd","audit/contracts/skill.cast-effect-timing.md","audit/manifest.json","audit/history.jsonl"],"tests":["remote_motion_splash_test.gd (PASS; 远端 SPECIAL_ATTACKING 创建、范围命中、攻击者硬直、本地无 CG_ATTACK、去重和 DuringTime 清理)","net_world_remote_action_test.gd (PASS)","net_world_motion_event_test.gd (PASS)","motion_splash_test.gd (PASS)","combat_fx_test.gd (PASS)","skill_test.gd (PASS)","git diff --check (PASS)"],"reason":"按 40250 ActorInstanceMotionEvent::ProcessMotionEventSpecialAttacking、InstanceBase::AttackProcess 和 ActorInstanceCollisionDetection::__SplashAttackProcess 补齐远端 actor 的 type 4 事件消费者:复用碰撞球、1000cm broad-phase、攻击可达性、去重、命中上限和受击处理;远端命中只作用于表现与动作,不伪造本地主角 CG_ATTACK。真实服务端结果、逐技能 MSA→MSE 挂点/颜色/混合、完整远端资源矩阵和中断清理仍保持 PARTIAL。"}
{"time":"2026-09-21T07:48:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["world.entity_spawn_state_sync"],"files":["project/net_world.gd","project/net_world_main_switch_test.gd","audit/contracts/world.entity-spawn-state-sync.md","audit/manifest.json","audit/history.jsonl"],"tests":["net_world_main_switch_test.gd (PASS; 新主 VID 切换清理旧 live actor、target/hover、sync-push/push、damage queue 和 chat tail)","net_world_reset_test.gd (PASS)","net_world_respawn_test.gd (PASS)","net_world_vis_test.gd (PASS)","git diff --check (PASS)"],"reason":"按 40250 CNetworkActorManager::SetMainActorVID 的主角色生命周期边界,主 VID 实际变化时先清理旧 live actors、目标/悬停和临时 presentation 状态,再注册新 VID;同 VID 重复通知不触发清理。EntityStore 快照重新可见时序、旧渐隐节点最终销毁、跨连接迟到 Move/Update 和完整渲染副作用顺序仍保持 PARTIAL。"}
{"time":"2026-09-21T07:58:36Z","event":"remediation_route_changed","result":"ROUTE_UPDATED","ids":["network.login.phase_flow","movement.keyboard.motion","combat.death.exp_drop","skill.cast.effect_timing","combat.flying_projectile"],"files":["audit/remediation-roadmap.md",".agents/skills/metin2-40250-parity-audit/SKILL.md",".agents/skills/metin2-40250-parity-audit/scripts/audit_ledger.py","audit/history.jsonl"],"reason":"将修复调度从按局部可修复差异推进改为按 P0 用户可玩链路推进;新增 223 个未闭合分支条目的当前快照、阶段路线、同一合同连续轮次限制和飞行物冻结规则。下一轮主合同为 network.login.phase_flow。"}
{"time":"2026-09-21T08:00:23Z","event":"remediation_route_corrected","result":"ROUTE_UPDATED","ids":["audit.issue_deduplication"],"files":["audit/remediation-roadmap.md",".agents/skills/metin2-40250-parity-audit/SKILL.md","audit/history.jsonl"],"reason":"将防重复规则从限制同一合同连续处理,修正为按明确的问题/分支 ID 去重;同一合同允许处理不同的 remaining 分支,只有同一问题在出现回归、实质实现变化或新证据时才可重开。"}
{"time":"2026-09-21T08:13:54Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix"],"files":["extension/src/net/classic/classic_session.h","extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_parser.h","extension/src/net/classic/classic_parser.cpp","extension/src/net/m2_client.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix net_classic_session_test (6 failures: duplicate PHASE_LOGIN, game GC_LOGIN_FAILURE, PHASE_CLOSE LoginPhase)","cmake --build build --target net_classic_session_test net_classic_stream_test net_loopback_test mtgodot -j2 (PASS)","net_classic_session_test (PASS)","net_classic_stream_test (PASS)","net_loopback_test (PASS)","ctest --test-dir build --output-on-failure -j1 (PASS; 23/23)","godot --headless --path project --script app_flow_lifecycle_test.gd --quit-after 10 (PASS)","godot --headless --path project --script p10_test.gd --quit-after 10 (PASS)","git diff --check (PASS)"],"reason":"按 40250 RecvPhasePacket/ClosePhase/SetLoginPhase、LoginPhase::RecvLoginFailurePacket 和 AccountConnector auth handlers 修复本地 auth/game phase 矩阵:PHASE_CLOSE 回 LoginPhase、重复 PHASE_AUTH/LOGIN 重新执行 handler、应用层登录拒绝保留 phase 并发出 login_failed、拒绝 auth success 延迟清理 auth stream;半包和空角色边界加入回归。真实服务端包序、完整 UI retry、旧 stream 竞态和可选安全分支仍保持 PARTIAL。"}
{"time":"2026-09-21T08:20:14Z","event":"implementation_hardening","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix"],"files":["extension/src/net/classic/classic_session.cpp","audit/history.jsonl"],"tests":["cmake --build build --target net_classic_session_test net_classic_stream_test net_loopback_test mtgodot -j2 (PASS)","net_classic_session_test (PASS)","net_classic_stream_test (PASS)","net_loopback_test (PASS)","ctest --test-dir build --output-on-failure -j1 (PASS; 23/23)","godot --headless --path project --script app_flow_lifecycle_test.gd --quit-after 10 (PASS)","godot --headless --path project --script p10_test.gd --quit-after 10 (PASS)","godot --headless --path project --script netplay_test.gd --quit-after 10 (PASS; exit 0)","audit_ledger.py validate (PASS)","git diff --check (PASS)"],"reason":"补强截断的 auth GC_LOGIN_FAILURE 分支:不再从不含分隔符的错误文本反向截取回调字符串,短包稳定回调 malformed 并保留 AUTH owner;重新完成原生、Godot 与审计校验。真实服务端包序、完整 UI retry、旧 stream 竞态和可选安全分支仍保持 PARTIAL。"}
{"time":"2026-09-21T08:36:46Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup","network.login.phase_flow/auth-game-phase-matrix"],"files":["extension/src/net/classic/classic_stream.h","extension/src/net/classic/classic_stream.cpp","extension/src/net/classic/classic_session.h","extension/src/net/classic/classic_session.cpp","extension/src/net/m2_client.h","extension/src/net/m2_client.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix net_classic_session_test (2 failures: pre-game peer close did not return to LoginPhase and did not clear retry password)","pre-fix net_classic_session_test (1 failure: DirectEnter connect failure remained Failed)","cmake --build build --target net_classic_session_test net_classic_stream_test net_loopback_test mtgodot -j2 (PASS)","net_classic_session_test (PASS)","net_classic_stream_test (PASS)","net_loopback_test (PASS)","ctest --test-dir build --output-on-failure -j1 (PASS; 23/23)","godot --headless --path project --script app_flow_lifecycle_test.gd --quit-after 10 (PASS)","godot --headless --path project --script p10_test.gd --quit-after 10 (PASS)","godot --headless --path project --script netplay_test.gd --quit-after 10 (PASS; exit 0)"],"reason":"按 40250 CNetworkStream::Process 的 OnRemoteDisconnect/OnConnectFailure 顺序修复本地 login-failure-retry-cleanup:断线前通知 phase ownerpeer close 回 SetLoginPhase 并清理旧 worldDirectEnter connect failure 回 LoginPhaseM2Client 保留重连请求并在旧 socket 清理后发出 world_reset/disconnected。真实服务端包序、完整 UI retry、GC_WARP live 顺序、旧 auth/game 竞态和可选安全分支仍保持 PARTIAL。"}
{"time":"2026-09-21T08:39:12Z","event":"implementation_hardening","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup","network.login.phase_flow/auth-game-phase-matrix"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/history.jsonl"],"tests":["net_classic_session_test (PASS; connect failure also asserts old send buffer is empty)","net_classic_stream_test (PASS)","net_loopback_test (PASS)","ctest --test-dir build --output-on-failure -j1 (PASS; 23/23)","mtgodot build (PASS)","godot --headless --path project --script app_flow_lifecycle_test.gd --quit-after 10 (PASS)","godot --headless --path project --script p10_test.gd --quit-after 10 (PASS)","godot --headless --path project --script netplay_test.gd --quit-after 10 (PASS; exit 0)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_phase_dispatch.py (PASS)"],"reason":"补齐同步 connect failure 的旧发送缓冲清理,确保 DirectEnter 的 LoginPhase 回退不会把失败连接的重试包留在旧 streamclassic phase/packet 结构审计没有发现未批准的分派差异。真实服务器包序和完整 UI retry 仍保持 PARTIAL。"}
{"time":"2026-09-21T09:16:12Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/legacy-text-wire-encoding","network.login.phase_flow/auth-game-phase-matrix"],"files":["extension/CMakeLists.txt","extension/src/net/text_codec.h","extension/src/net/text_codec.cpp","extension/src/net/classic/wire_classic.h","extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_parser.cpp","extension/src/net/m2_client.cpp","extension/tests/net_text_codec_test.cpp","audit/contracts/network.login.phase-flow.md","audit/history.jsonl"],"tests":["net_text_codec_test (PASS; 24-byte GB2312 boundary holds 12 CJK characters)","ctest --test-dir build --output-on-failure -j2 (PASS; 23/23)","godot --headless --path project --script app_flow_lifecycle_test.gd --quit-after 10 (PASS)","godot --headless --path project --script netplay_test.gd --quit-after 10 (PASS; exit 0)","MT_CLASSIC_AUTH=1 build/extension/net_classic_e2e <redacted-live-account> (PASS; auth -> char_select -> loading -> PHASE_GAME)","git diff --check (PASS)"],"reason":"按 40250 的 24-byte fixed-name wire 字段修正客户端内部 UTF-8 与 GB2312/兼容编码边界;角色/公会/NPC/聊天/任务/商店等文本发送前编码、接收后解码,严格校验按 wire 字节而非 UTF-8 字节;同时将 GCLoginSuccess4 的 SimplePlayer/整包布局修正为 63/329 字节,消除真实服务端角色列表包被误判为不完整的问题。真实服务端成功包序已验证,但失败/重试完整 UI、DirectEnter/GC_WARP live 顺序和可选安全分支仍保持 PARTIAL。"}
{"time":"2026-09-21T09:26:49Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/live-package-order"],"files":["extension/tools/net_classic_e2e.cpp","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix live wrong-password probe (FAIL: real WRONGPWD was reported only as an 8-second timeout)","cmake --build build --target net_classic_e2e net_classic_session_test net_classic_stream_test net_loopback_test mtgodot -j2 (PASS)","ctest --test-dir build --output-on-failure -j2 (PASS; 23/23)","MT_CLASSIC_AUTH=1 build/extension/net_classic_e2e <redacted-live-account> (PASS; auth -> four slots -> select -> loading -> PHASE_GAME)","MT_CLASSIC_AUTH=1 build/extension/net_classic_e2e <redacted-live-account-invalid-password> (PASS as expected probe result; WRONGPWD callback, exit 5)","MT_CLASSIC_AUTH=1 build/extension/net_classic_e2e <redacted-live-account-unavailable-game-port> (PASS as expected probe result; connect-failed callback, exit 5)","godot --headless --path project --script app_flow_lifecycle_test.gd --quit-after 10 (PASS)","godot --headless --path project --script netplay_test.gd --quit-after 10 (PASS; exit 0)","git diff --check (PASS)"],"reason":"按 40250 AccountConnector/PythonNetworkStream 的登录失败回调语义修正 live probe:应用层 WRONGPWD/BESAMEKEY 通过 on_login_failure 立即结束探针,已建立 game 连接的 remote-disconnect 通过 on_remote_disconnect 保留原始故障证据,不再把合法失败回调误报为 timeout。真实成功包序和两种失败回调已取证;空角色、PHASE_CLOSE、peer close、DirectEnter/GC_WARP 完整包序及可选安全分支仍未闭合,因此合同保持 PARTIAL。"}
{"time":"2026-09-21T09:33:47Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/auth-peer-close-owner"],"files":["extension/src/net/classic/classic_session.cpp","extension/src/net/m2_client.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix net_classic_session_test (FAIL: auth peer close remained ClassicSession::Failed instead of the 40250 Offline owner)","cmake --build build --target net_classic_session_test net_classic_stream_test net_loopback_test net_classic_e2e mtgodot -j2 (PASS)","build/extension/net_classic_session_test (PASS; auth peer close -> Offline owner)","ctest --test-dir build --output-on-failure -j2 (PASS; 23/23)","godot --headless --path project --script app_flow_lifecycle_test.gd --quit-after 10 (PASS)","godot --headless --path project --script p10_test.gd --quit-after 10 (PASS)","godot --headless --path project --script netplay_test.gd --quit-after 10 (PASS; exit 0)","MT_CLASSIC_AUTH=1 build/extension/net_classic_e2e <redacted-live-account> (PASS; auth -> four slots -> select -> loading -> PHASE_GAME)","MT_CLASSIC_AUTH=1 build/extension/net_classic_e2e <redacted-live-account-invalid-password> (PASS as expected probe result; WRONGPWD callback, exit 5)","MT_CLASSIC_AUTH=1 build/extension/net_classic_e2e <redacted-live-account-unavailable-game-port> (PASS as expected probe result; connect-failed callback, exit 5)","audit_ledger.py validate (PASS)","git diff --check (PASS)"],"reason":"按 40250 CAccountConnector::OnRemoteDisconnect -> __OfflineState_Set 修复认证端 peer closeClassicSession 不再把 auth 传输断开压成 Failed,而是回 Offline ownerM2Client 将该 native 状态桥接为 login_failed + 可重试 host 状态,避免 Godot 登录阶段卡在 GameLogin。真实成功、认证拒绝和游戏连接失败探针仍通过;完整 UI retry、PHASE_CLOSE/peer-close live 包序、DirectEnter/GC_WARP 和可选安全分支仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T09:53:05Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/ui-login-owner"],"files":["project/app_flow.gd","project/app_flow_lifecycle_test.gd","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix app_flow_lifecycle_test.gd (FAIL: login failure replaced LoginPhase UI and lost password focus path; 2 checks)","godot --headless --path project --script app_flow_lifecycle_test.gd --quit-after 10 (PASS)","godot --headless --path project --script p10_test.gd --quit-after 10 (PASS)","godot --headless --path project --script netplay_test.gd --quit-after 10 (PASS; exit 0)","ctest --test-dir build --output-on-failure -j2 (PASS; 23/23)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_phase_dispatch.py (PASS)"],"reason":"按 40250 PythonNetworkStream::__RecvLoginFailurePacket -> intrologin.OnLoginFailure 的 UI owner 语义修复 AppFlow:LOGIN 阶段失败不再重建整个登录层,保留原 CanvasLayer、密码字段和 Status,并请求密码框焦点;只有失败来自 SELECT/其它阶段且没有 LoginPhase owner 时才回到登录页。认证/握手/Loading 静默、跨阶段 retry、真实失败包序、PHASE_CLOSE/peer-close live 顺序和可选安全分支仍保持 PARTIAL。"}
{"time":"2026-09-21T10:11:01Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/cross-phase-login-leave-owner"],"files":["extension/src/net/classic/classic_parser.h","extension/src/net/classic/classic_parser.cpp","extension/src/net/classic/classic_session.h","extension/src/net/classic/classic_session.cpp","extension/src/net/m2_client.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix net_classic_session_test (FAIL: PHASE_LOGIN clears the previous character-list owner before retry; PHASE_LOGIN runs the previous GamePhase leave cleanup before retry; 2 checks)","cmake --build build -j2 --target net_classic_session_test mtgodot (PASS)","build/extension/net_classic_session_test (PASS)","build/extension/net_classic_stream_test (PASS)","build/extension/net_loopback_test (PASS)","ctest --test-dir build --output-on-failure -j2 (PASS; 23/23)","godot --headless --path project --script app_flow_lifecycle_test.gd --quit-after 10 (PASS)","godot --headless --path project --script p10_test.gd --quit-after 10 (PASS)","godot --headless --path project --script netplay_test.gd --quit-after 10 (PASS; exit 0)","godot --headless --path project --script disconnect_world_reset_test.gd --quit-after 10 (PASS)","audit_phase_dispatch.py (PASS)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","git diff --check (PASS)"],"reason":"按 40250 SetLoginPhase 在旧 phase 非 Login 时先执行 m_phaseLeaveFunc.Run、普通分支发送登录包后 __ClearSelectCharacterData 的语义,新增 ClassicSession::enter_login_phase 统一直接 PHASE_LOGIN、PHASE_CLOSE 和 peer-close 的 Login owner 转换;Game owner 先清理旧 world,普通非 DirectEnter 清理旧角色列表;M2Client 在 phase-leave 后发 world_reset,并在 LoginPhase 重入时清除 classic_list_emitted,避免同一 pump 的新角色列表被旧锁吞掉。真实服务端跨阶段重试、旧新 socket 竞态、完整 UI retry、重复进入 live 包序和可选安全分支仍保持 PARTIAL。"}
{"time":"2026-09-21T10:23:42Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.character_select.create_delete","network.security_encoding"],"files":["extension/src/net/text_codec.cpp","extension/src/net/text_codec.h","extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_parser.cpp","extension/src/net/m2_client.cpp","extension/tests/net_text_codec_test.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.character-select.md","audit/contracts/network.security-encoding.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix net_classic_session_test (FAIL: Chinese create packet size assertion included the undrained login packet; corrected the fixture to isolate the actual create packet)","cmake --build build -j2 --target net_text_codec_test net_classic_session_test net_classic_stream_test net_loopback_test mtgodot (PASS)","build/extension/net_text_codec_test (PASS)","build/extension/net_classic_session_test (PASS)","ctest --test-dir build --output-on-failure -j2 (PASS; 23/23)","godot --headless --path project --script app_flow_lifecycle_test.gd --quit-after 10 (PASS)","godot --headless --path project --script char_create_delete_test.gd --quit-after 10 (PASS)","godot --headless --path project --script test_intro_select_parity.gd --quit-after 10 (PASS; 21/21)","godot --headless --path project --script netplay_test.gd --quit-after 10 (PASS)","git diff --check (PASS)"],"reason":"按 40250 中文 fixed char[] 语义保留客户端内部 UTF-8,并在 classic 网络边界使用 Windows CP936 或 POSIX GB2312/GBK 转码;wire_text_fits 按转码后的字节数校验,角色创建/改名实际包验证 12 个中文字符占 24 字节、13 个被拒绝,接收路径解回 UTF-8。无系统 codepage codec 的平台改为拒绝高位字节,避免把 UTF-8 原样泄漏到 40250 字段。其它 locale codepage、legacy/optional security、真实服务端中文建号包序仍保持 PARTIAL。"}
{"time":"2026-09-21T10:24:31Z","event":"implementation_hardening","result":"PARTIAL","ids":["network.security_encoding"],"files":["extension/src/net/text_codec.cpp","audit/contracts/network.security-encoding.md","audit/manifest.json","audit/history.jsonl"],"tests":["net_text_codec_test (PASS)","net_classic_session_test (PASS)","net_classic_stream_test (PASS)","net_loopback_test (PASS)","ctest --test-dir build --output-on-failure -j2 (PASS; 23/23)","Godot app_flow_lifecycle_test.gd, char_create_delete_test.gd, test_intro_select_parity.gd and netplay_test.gd (PASS)","git diff --check (PASS)","audit_ledger.py validate (PASS; 45 contracts)"],"reason":"收口无 Windows/iconv 平台的 fallback 解码路径:不再直接把高位 legacy bytes 当作 UTF-8 返回;ASCII 正常解码,非法/不可表示字节进入替换路径,发送端也拒绝高位 UTF-8,避免 40250 固定字段出现编码污染。中文 CP936/GB2312 主路径保持通过,其它 locale codepage 和完整真实服务端证据仍保持 PARTIAL。"}
{"time":"2026-09-21T10:31:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/ticket-slot-warp-order/direct-enter-login2-packet"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix net_classic_session_test (FAIL: GC_WARP inherited the old PHASE_GAME marker)","cmake --build build-debug --target net_classic_session_test -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test mtgodot -j4 (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","Godot app_flow_lifecycle_test.gd, p10_test.gd, netplay_test.gd and disconnect_world_reset_test.gd (PASS)","DirectEnter/GC_WARP CG_LOGIN2 header, sequence byte, login key and selected-slot retention (PASS)","git diff --check (PASS)","audit_ledger.py validate (PASS; 45 contracts)","audit_phase_dispatch.py (PASS)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)"],"reason":"按 40250 ConnectGameServer/CNetworkStream::Connect 的新传输属主语义,GC_WARP 复用原 session、selected slot 和 login key,但清除旧 socket 的 PHASE_GAME 标记;只有替换连接再次收到 PHASE_GAME 才标记为已建立游戏连接。真实 Ubuntu 40250 的 DirectEnter/GC_WARP 包序仍缺 live fixture,合同保持 PARTIAL。"}
{"time":"2026-09-21T10:38:21Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/auth-handshake-phase-dispatch"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix net_classic_session_test (FAIL: auth handshake ignored-phase guard missing; GC_LOGIN_FAILURE triggered login failure before PHASE_AUTH)","cmake --build build-debug --target net_classic_session_test -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test mtgodot -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","Godot app_flow_lifecycle_test.gd, p10_test.gd, netplay_test.gd and disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_ledger.py validate (PASS; 45 contracts)","git diff --check (PASS)"],"reason":"按 40250 CAccountConnector::__HandshakeState_Process 与 __AuthState_Process 的两张状态分派表,在 ClassicSession::on_auth_packet 入口增加认证 owner 前置条件:PHASE_AUTH 之前的应用层登录包不触发登录 UI,进入 PHASE_AUTH 后保留 CG_LOGIN3、失败回调和 login-key 路径。认证/Loading 其它静默分支、真实服务端失败包序和完整 UI retry 仍保持 PARTIAL。"}
{"time":"2026-09-21T11:05:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/loading-phase-silent"],"files":["extension/src/net/classic/classic_stream.h","extension/src/net/classic/classic_stream.cpp","extension/src/net/classic/classic_session.h","extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix net_classic_session_test (FAIL: unknown Loading packet follows RecvErrorPacket without phase loss)","ASAN net_classic_session_test (PASS; no heap-use-after-free after callback-lifetime hardening)","cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test mtgodot -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","Godot app_flow_lifecycle_test.gd, p10_test.gd, netplay_test.gd and disconnect_world_reset_test.gd (PASS; netplay exit 0)","audit_phase_dispatch.py (PASS)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_ledger.py refresh --write; report --write; validate (PASS; 45 contracts)","git diff --check (PASS)"],"reason":"按 40250 PythonNetworkStreamPhaseLoading::LoadingPhase -> GamePhase -> RecvErrorPacket/ClearRecvBuffer 的语义,为 active ClassicSession 增加统一 unknown GC header owner:清理当前未读 burst、保留 Loading/Game phase 和 socket;独立 ClassicStream 未绑定 owner 时仍保持严格未知头断开。ASAN 同时发现并验证修复 ClassicSession 析构期间 stream Offline 回调写入已析构 m_last_error 的生命周期缺陷。真实服务器 Loading 静默未知包、跨阶段完整 UI retry、重复进入以及其它认证静默分支仍未取证,合同保持 PARTIAL。"}
{"time":"2026-09-21T11:25:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/auth-unknown-header-owner"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix net_classic_session_test (FAIL: unknown auth packet keeps AUTH owner and socket alive)","cmake --build build-debug --target net_classic_session_test -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","audit phase/packet structural checks pending final round verification","git diff --check pending final round verification"],"reason":"按 40250 CAccountConnector::__AuthState_Process 的未匹配包语义,为 ClassicSession 抽取统一 active phase-owner unknown-header 回调并同时绑定 auth/game stream;未知应用头清理当前未读 burst但不触发 transport disconnect,独立未绑定 ClassicStream 仍保持严格错误。真实服务器可选认证包、跨阶段完整 UI retry、重复进入包序仍未取证,合同保持 PARTIAL。"}
{"time":"2026-09-21T11:34:00Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/auth-unknown-header-owner"],"tests":["ASAN net_classic_session_test (PASS)","cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test mtgodot -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","Godot app_flow_lifecycle_test.gd (PASS)","Godot p10_test.gd (PASS)","Godot netplay_test.gd (exit 0)","Godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_ledger.py refresh --write (PASS; 20 fingerprints refreshed)","audit_ledger.py report --write (PASS)","audit_ledger.py validate (PASS; 45 contracts)","git diff --check (PASS)"],"reason":"认证未知应用头不再使 active AUTH owner 进入 FailedASAN、native、CTest、Godot 和结构审计均通过。真实服务器可选认证包、跨阶段完整 UI retry、重复进入包序仍未取证,合同保持 PARTIAL。"}
{"time":"2026-09-21T12:05:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/auth-connect-failure-owner"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix net_classic_session_test (FAIL: auth connect failure returns to the 40250 Offline owner)","cmake --build build-debug --target net_classic_session_test -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","auth retry fixture verifies old stream cleanup, replacement accept and one CG_LOGIN3 (PASS)","final ASAN/native/Godot/audit verification recorded in follow-up test_run"],"reason":"按 40250 CAccountConnector::OnConnectFailure -> __OfflineState_Set,为 auth ClassicStream 增加 connect-failure owner:记录错误、清理认证状态、回到 Offline,随后允许同一 session 用新 socket重试并重新发送 CG_LOGIN3;此前通用 state callback 会把 auth 连接失败误报为 Failed。真实服务器连接失败 UI 包序和 Windows 可视化 retry 仍未取证,合同保持 PARTIAL。"}
{"time":"2026-09-21T12:12:00Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/auth-connect-failure-owner"],"tests":["ASAN net_classic_session_test (PASS)","cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test mtgodot -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","Godot app_flow_lifecycle_test.gd (PASS)","Godot p10_test.gd (PASS)","Godot netplay_test.gd (exit 0)","Godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_ledger.py refresh --write (PASS; 20 fingerprints refreshed)","audit_ledger.py report --write (PASS)","audit_ledger.py validate (PASS; 45 contracts)","git diff --check (PASS)"],"reason":"认证 TCP 连接失败现在回到 Offline owner,并且同一 session 的旧 stream 清理和重试包序通过;完整 native/Godot/账本验证通过。真实服务器空角色、PHASE_CLOSE/peer-close/DirectEnter/GC_WARP 包序、可选认证分支和 Windows UI retry 仍未取证,合同保持 PARTIAL。"}
{"time":"2026-09-21T12:25:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/optional-security-branches/hybridcrypt-explicit-deployment-guard"],"files":["extension/src/net/classic/classic_stream.h","extension/src/net/classic/classic_stream.cpp","extension/src/net/classic/classic_session.h","extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_parser.h","extension/src/net/m2_client.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix net_classic_session_test (FAIL: HybridCrypt packet raises an explicit deployment guard; HybridCrypt deployment guard preserves the LoginPhase owner)","cmake --build build-debug --target net_classic_session_test mtgodot -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)"],"reason":"按 40250 CAccountConnector/PythonNetworkStream 对 HybridCrypt keys/SDB 的 consume-and-return 语义,当前客户端增加动态可选安全包通知和 M2Client optional_security_required 部署前置;不再静默丢包或误断线,phase/socket owner 保持不变。完整 EterPack HybridCrypt 注入、Panama IV、Matrix/Passpod UI 和 HS/XTrap response 仍未实现,合同保持 PARTIAL。"}
{"time":"2026-09-21T12:31:00Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/optional-security-branches/hybridcrypt-explicit-deployment-guard"],"tests":["net_classic_session_test (PASS)","net_classic_stream_test (PASS)","net_loopback_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","ASAN net_classic_session_test (PASS; detect_leaks=0)","Godot app_flow_lifecycle_test.gd (PASS)","Godot p10_test.gd (PASS)","Godot netplay_test.gd (exit 0)","Godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_ledger.py refresh --write (PASS; 28 fingerprints refreshed)","audit_ledger.py report --write (PASS)","audit_ledger.py validate (PASS; 45 contracts)","git diff --check (PASS)","manifest.json and history.jsonl JSON validation (PASS; 423 records)"],"reason":"HybridCrypt 动态帧显式 deployment guard、phase owner 保留和后续包边界回归通过;完整可选安全 runtime 和真实服务器包序仍未取证,合同保持 PARTIAL。"}
{"time":"2026-09-21T12:45:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/phase-close-reconnect-owner"],"files":["extension/src/net/m2_client.cpp","project/app_flow.gd","project/ui/reconnect_ui.gd","project/app_flow_lifecycle_test.gd","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix app_flow_lifecycle_test.gd (FAIL: game-side LoginPhase transition enters reconnecting GAME; shows reconnect overlay; re-enters remembered character slot; 3 checks)"],"reason":"按 40250 RecvPhasePacket(PHASE_CLOSE) -> ClosePhase -> SetLoginPhase 的 owner 顺序,修复游戏态显式 PHASE_CLOSEM2Client 在旧 GamePhase world leave/reset 完成后发出一次 disconnected 并保留 login-key retryAppFlow 同时消费 phase_changed(login/close) 作为阶段-only 兜底,ReconnectUI 继续由单一重连属主计时。登录/选人/Loading 不扩大为普通断线,合同保持 PARTIAL。"}
{"time":"2026-09-21T12:52:00Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/phase-close-reconnect-owner"],"tests":["cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test mtgodot -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","ASAN net_classic_session_test (PASS; detect_leaks=0)","Godot app_flow_lifecycle_test.gd (PASS)","Godot p10_test.gd (PASS)","Godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","git diff --check (PASS)"],"reason":"PHASE_CLOSE 的 native disconnected owner、phase-only LoginPhase fallback、保留 GameScene、角色槽位重入和 entered_game 收口均通过;真实服务端 PHASE_CLOSE/peer-close 包序、完整跨阶段 UI retry 和 DirectEnter/GC_WARP live 证据仍未取证,合同保持 PARTIAL。"}
{"time":"2026-09-21T13:10:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/phase-close-loading-owner"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix net_classic_session_test (FAIL: Loading PHASE_CLOSE clears the old world before login retry; Loading PHASE_CLOSE notifies the host after the old world is cleared; 2 checks)"],"reason":"按 40250 SetLoginPhase 在旧 phase 非 Login 时先运行 m_phaseLeaveFunc.Run 的语义,修复 ClassicSession::enter_login_phaseLoading 和 InGame 统一先 reset_for_map_change、通知 on_phase_leave,再切回 LoggingIn 并发送 LoginPhase 包;不是针对单个 Loading 包或 actor 的特判,合同保持 PARTIAL。"}
{"time":"2026-09-21T13:18:00Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/phase-close-loading-owner"],"tests":["cmake --build build-debug --target net_classic_session_test -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","audit ledger/document synchronization pending final round verification"],"reason":"Loading PHASE_CLOSE 的旧 world 清理和宿主通知回归通过;仍需完成相关网络、CTest、ASAN、结构审计和最终账本校验,真实服务端 Loading close/peer-close 包序仍未取证,合同保持 PARTIAL。"}
{"time":"2026-09-21T13:32:00Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/phase-close-loading-owner"],"tests":["cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test mtgodot -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","ASAN net_classic_session_test (PASS; detect_leaks=0)","Godot app_flow_lifecycle_test.gd (PASS)","Godot p10_test.gd (PASS)","Godot netplay_test.gd (exit 0)","Godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_ledger.py refresh --write (PASS; 20 fingerprints refreshed)","audit_ledger.py report --write (PASS)","audit_ledger.py validate (PASS; 45 contracts)","git diff --check (PASS)","manifest.json and history.jsonl JSON validation (PASS; 428 records before this append)"],"reason":"Loading 与 InGame 的 PHASE_CLOSE 都按 40250 旧 phase-leave owner 清理 world 后再进入 LoginPhase;专项、CTest、ASAN、Godot、结构审计和账本均通过。真实服务器 Loading close/peer-close 包序、完整跨阶段 UI retry、空角色 live 和 DirectEnter/GC_WARP live 证据仍未取证,合同保持 PARTIAL。"}
{"time":"2026-09-21T13:45:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/warp-connect-failure-retry-owner","network.login.phase_flow/auth-game-phase-matrix"],"files":["extension/src/net/m2_client.cpp","extension/src/net/m2_client.h","project/app_flow_lifecycle_test.gd","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix app_flow_lifecycle_test.gd (FAIL: fast reconnect connect failure keeps the native reconnect owner armed; GC_WARP connect failure keeps the native reconnect owner armed; 2 checks)","godot --headless --path project --script app_flow_lifecycle_test.gd --quit-after 10 (PASS after fix)"],"reason":"按 40250 RecvWarpPacket -> Connect -> OnConnectFailure -> SetLoginPhase 的 owner 语义,修复 ClassicSession connect_warp 两个宿主入口:同步失败后保留游戏侧 retry owner、清理 GC_WARP 旧 UI/world latch、发出一次 disconnected,不再把已回到 LoginPhase 的替换连接误报为终态 Failed/login_failed;合同保持 PARTIAL。"}
{"time":"2026-09-21T13:46:00Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/warp-connect-failure-retry-owner","network.login.phase_flow/auth-game-phase-matrix"],"tests":["cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test mtgodot -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","ASAN net_classic_session_test (PASS; detect_leaks=0)","Godot app_flow_lifecycle_test.gd (PASS)","Godot p10_test.gd (PASS)","Godot netplay_test.gd (exit 0)","Godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","git diff --check (PASS)"],"reason":"warp connect failure retry-owner 的本地 native bridge invariant、AppFlow phase-only owner、原生网络测试、CTest、ASAN、Godot 回归和阶段分派审计均通过;真实服务器 GC_WARP/DirectEnter 包序、PHASE_CLOSE/peer-close live UI 顺序和完整跨阶段 retry 仍未取证,合同保持 PARTIAL。"}
{"time":"2026-09-21T11:50:28Z","event":"live_evidence_refresh","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/live-package-order","network.login.phase_flow/real-server-sequence"],"tests":["build-debug/extension/net_classic_e2e configured game channel (PASS: auth -> four slots -> select -> loading -> PHASE_GAME; 21 entities observed)","build-debug/extension/net_classic_e2e configured game channel with invalid password (PASS as expected probe result: WRONGPWD callback before timeout; exit 5)","build-debug/extension/net_classic_e2e unavailable game channel (PASS as expected probe result: connect failed before timeout; exit 5)"],"reason":"补充当前 40250 配置端口的只读真实包序证据,确认成功认证/四槽角色列表/选角/Loading/PHASE_GAME、应用层 WRONGPWD 和游戏连接失败的观察边界;空角色、服务器 PHASE_CLOSE、建立连接后的 peer close、DirectEnter/GC_WARP 和完整重试包序仍缺少真实 fixture,因此不关闭剩余分支。"}
{"time":"2026-09-21T11:51:39Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/live-package-order","network.login.phase_flow/real-server-sequence"],"tests":["ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","ASAN net_classic_session_test (PASS; detect_leaks=0)","Godot app_flow_lifecycle_test.gd (PASS)","Godot p10_test.gd (PASS)","Godot netplay_test.gd (exit 0)","Godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_ledger.py refresh --write; report --write; validate (PASS; 45 contracts)","manifest.json/history.jsonl JSON validation (PASS)","git diff --check (PASS)"],"reason":"在真实包序证据刷新后完成本地 native、ASAN、Godot、阶段/包结构和账本回归;本轮没有新增生产代码修复,remaining 中的空角色、PHASE_CLOSE、peer close、DirectEnter/GC_WARP 和完整 UI retry 仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T11:57:55Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/empty-reconnect-select-owner"],"files":["project/app_flow.gd","project/app_flow_lifecycle_test.gd","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix godot app_flow_lifecycle_test.gd (FAIL: empty reconnect character list returns to the SELECT owner)","post-fix godot app_flow_lifecycle_test.gd (PASS)"],"reason":"按 40250 RecvPhasePacket(PHASE_SELECT) -> SetSelectCharacterPhase -> SelectCharacterWindow.Refresh 的阶段 owner 语义,修复重连角色列表为空或记忆槽失效时的 AppFlow 分支:不再把过期槽位发送给 native bridge,也不再保留旧 GameScene/重连遮罩;释放旧场景并让 SELECT 成为唯一 owner。真实空角色账号 fixture 仍缺失,合同保持 PARTIAL。"}
{"time":"2026-09-21T11:58:00Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/empty-reconnect-select-owner"],"tests":["ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","ASAN net_classic_session_test (PASS; detect_leaks=0)","Godot app_flow_lifecycle_test.gd (PASS)","Godot p10_test.gd (PASS)","Godot netplay_test.gd (exit 0)","Godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_ledger.py refresh --write; report --write; validate (PASS; 45 contracts)","manifest.json/history.jsonl JSON validation (PASS)","git diff --check (PASS)"],"reason":"空重连角色列表的专项回归、原生网络回归、CTest、ASAN、Godot、阶段/包结构审计和账本校验均通过;真实服务端空角色、PHASE_CLOSE/peer-close、DirectEnter/GC_WARP 包序、完整跨阶段 UI retry 和可选安全 runtime 仍未取证,合同保持 PARTIAL。"}
{"time":"2026-09-21T12:03:50Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/pre-game-phase-login-ui-owner"],"files":["project/app_flow.gd","project/app_flow_lifecycle_test.gd","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix godot app_flow_lifecycle_test.gd (FAIL: pre-game LoginPhase transition replaces the SELECT owner)","post-fix godot app_flow_lifecycle_test.gd (PASS)"],"reason":"按 40250 RecvPhasePacket(PHASE_CLOSE) -> ClosePhase -> SetLoginPhase -> LoginWindow 的 owner 顺序,修复 SELECT/Loading 状态收到 phase-only login/close 事件时仍保留旧选人 UI 的差异;游戏态仍保留已有 disconnected/reconnect owner,非游戏态切换到唯一 LoginPhase owner。真实服务端 PHASE_CLOSE/peer-close UI 包序和完整跨阶段 retry 仍缺 live fixture,合同保持 PARTIAL。"}
{"time":"2026-09-21T12:04:00Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/pre-game-phase-login-ui-owner"],"tests":["ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","ASAN net_classic_session_test (PASS; detect_leaks=0)","Godot app_flow_lifecycle_test.gd (PASS)","Godot p10_test.gd (PASS)","Godot netplay_test.gd (exit 0)","Godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_ledger.py refresh --write; report --write; validate (PASS; 45 contracts)","manifest.json/history.jsonl JSON validation (PASS)","git diff --check (PASS)"],"reason":"pre-game LoginPhase owner 专项测试、原生网络、CTest、ASAN、Godot 和账本校验均通过;真实服务器 PHASE_CLOSE/peer-close UI 包序、完整跨阶段 retry、DirectEnter/GC_WARP live 包序和可选安全 runtime 仍未取证,合同保持 PARTIAL。"}
{"time":"2026-09-21T12:12:51Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/ticket-slot-warp-order/direct-enter-loading-select-packet"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix net_classic_session_test (FAIL: DirectEnter SetLoadingPhase sends the reference CG_PLAYER_SELECT)","pre-fix live DirectEnter probe (FAIL: authenticated slot selection reached Loading but timed out before PHASE_GAME)","post-fix net_classic_session_test (PASS; DirectEnter CG_PLAYER_SELECT header, wire length and selected slot)","reference source re-check (PASS: introloading.LoadingWindow.Open calls SendSelectCharacterPacket(chrSlot))"],"reason":"重新核对 40250 introloading.py 和实时行为后,证明此前 direct-enter-login2-packet 分支中“DirectEnter 不发送 CG_PLAYER_SELECT”的结论已被新证据实质性推翻;按实际调用链在 PHASE_SELECT 的 DirectEnter 分支补发 selected slot 的 CG_PLAYER_SELECT,再进入 Loading。该分支是新证据导致的独立修复,不是重复修复已有分支;完整回归和实时成功证据记录在后续 test_run 中,合同保持 PARTIAL。"}
{"time":"2026-09-21T12:12:51Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/ticket-slot-warp-order/direct-enter-loading-select-packet","network.login.phase_flow/auth-game-phase-matrix/live-package-order","network.login.phase_flow/real-server-sequence"],"tests":["cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test mtgodot net_classic_e2e -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","ASAN net_classic_session_test (PASS; detect_leaks=0)","Godot app_flow_lifecycle_test.gd (PASS)","Godot p10_test.gd (PASS)","Godot netplay_test.gd (exit 0)","Godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS; no payload differences)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","redacted live DirectEnter probe (PASS: CG_PLAYER_SELECT -> PHASE_LOADING -> PHASE_GAME; 21 entities, 21 inventory slots, level 105)","audit_ledger.py refresh --write; report --write; validate (PASS; 45 contracts)","manifest.json/history.jsonl JSON validation (PASS)","git diff --check (PASS)"],"reason":"按 40250 LoadingWindow.Open 的真实调用链修复 DirectEnter 角色选择包后,本地协议矩阵、CTest、ASAN、Godot 生命周期和结构审计均通过,真实配置服务端也从 Loading 进入 PHASE_GAME。GC_WARP 真实包序、空角色、PHASE_CLOSE/peer-close live、完整跨阶段 UI retry 和可选安全 runtime 仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T12:24:33Z","event":"live_evidence_refresh","result":"PARTIAL","ids":["network.login.phase_flow/ticket-slot-warp-order/gc-warp-live-package-order","network.login.phase_flow/auth-game-phase-matrix/live-package-order","network.login.phase_flow/real-server-sequence"],"files":["extension/tools/net_classic_e2e.cpp","project/live_smoke_test.gd","extension/src/net/classic/classic_session.h","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/remediation-roadmap.md","audit/history.jsonl"],"tests":["pre-fix production test: not applicable; this was a verification branch and the existing local GC_WARP implementation already matched the reference, so no artificial failing result was recorded","redacted Godot live smoke with MT_SMOKE_WARP_COMMAND=/warp (PASS report: world_reset, replacement transport, second entered_game and world rebuild)","redacted build-debug/extension/net_classic_e2e with MT_CLASSIC_WARP_COMMAND=/warp (PASS: GC_WARP reconnect -> configured game channel; second PHASE_GAME)"],"reason":"按 40250 CHARACTER::WarpSet -> GC_WARP -> RecvWarpPacket -> CNetworkStream::Connect 的真实调用链增加可重复 live/e2e 触发入口,并验证当前 M2Client/ClassicSession 的旧 world 清理、login key/selected slot 保留、replacement CG_LOGIN2、DirectEnter CG_PLAYER_SELECT、Loading 和第二次 PHASE_GAME。没有发现生产连接逻辑差异,因此本轮没有修改连接行为;完整失败回退、空角色、PHASE_CLOSE/peer-close live 证据仍保持 PARTIAL。"}
{"time":"2026-09-21T12:49:10Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/peer-close-login-owner"],"files":["project/app_flow.gd","project/app_flow_lifecycle_test.gd","project/p10_test.gd","project/live_smoke_test.gd","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_session.h","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/remediation-roadmap.md","audit/history.jsonl"],"tests":["pre-fix app_flow_lifecycle_test.gd (FAIL: game peer close retained GAME/reconnect overlay/remembered slot; phase-only LoginPhase retained GAME; empty list did not reach SELECT)"],"reason":"按 40250 EterLib/NetStream::OnRemoteDisconnect -> PythonNetworkStreamEvent::OnRemoteDisconnect -> networkmodule.SetLoginPhase 的完整 owner 语义,修复 AppFlow:游戏 peer close 和 game-side phase-only Login/Close 都释放 GameScene、清除 reconnect state、切换到唯一 LoginPhase owner;不再挂接自动 ReconnectUI 或自动重入旧角色。M2Client 的 login key 和显式 reconnect API 保留,真实 /logout peer-close 的 UI owner 由 Godot live smoke 验证;服务器主动 PHASE_CLOSE、空角色 live、完整 retry 和重复进入包序仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T12:49:10Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/peer-close-login-owner","network.login.phase_flow/auth-game-phase-matrix/live-package-order","network.login.phase_flow/real-server-sequence"],"tests":["cmake --build build-debug --target net_entity_test net_classic_session_test net_classic_stream_test net_loopback_test mtgodot net_classic_e2e -j4 (PASS)","build-debug/extension/net_entity_test (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","ASAN_OPTIONS=detect_leaks=0 build-asan/extension/net_classic_session_test (PASS)","godot app_flow_lifecycle_test.gd (PASS)","godot p10_test.gd (PASS)","godot netplay_test.gd (exit 0)","godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","redacted Godot live smoke MT_SMOKE_PHASE_COMMAND=/logout (functional report PASS: PHASE_GAME -> world_reset -> peer closed -> LoginPhase owner; wrapper exit gate failed on pre-existing 4 ParticlesShaderRD/RID leaks)","audit_ledger.py refresh --write (PASS; 31 changes written)","audit_ledger.py report --write (PASS)","audit_ledger.py validate (PASS; 45 contracts)","manifest.json JSON validation (PASS)","git diff --check (PASS)"],"reason":"peer-close LoginPhase owner 的修复前失败、修复后本地行为和真实 40250 /logout 功能路径均有证据;外层 live smoke 的 shader leak gate 是既有渲染资源问题,不把它误记为网络失败。合同仍为 PARTIAL,下一候选是服务器主动 PHASE_CLOSE 的真实或等价 fixture。"}
{"time":"2026-09-21T12:50:00Z","event":"implementation_hardening","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/peer-close-login-owner"],"files":["script/live_smoke_test.sh"],"tests":["./script/live_smoke_test.sh --help (PASS; documents MT_SMOKE_PHASE_COMMAND=/logout live owner probe)","git diff --check (PASS)"],"reason":"为后续 AI/维护者保留可重复的真实 peer-close owner 入口,在 live smoke 帮助中公开 MT_SMOKE_PHASE_COMMAND;不改变网络行为,合同保持 PARTIAL。"}
{"time":"2026-09-21T12:52:00Z","event":"implementation_hardening","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/peer-close-login-owner"],"files":["project/app_flow_lifecycle_test.gd"],"tests":["godot --headless --path project --script app_flow_lifecycle_test.gd --quit-after 10 (PASS; explicit phase_changed(\\\"close\\\") releases GameScene)","godot --headless --path project --script p10_test.gd --quit-after 10 (PASS)","git diff --check (PASS)"],"reason":"补充 AppFlow 对显式 PHASE_CLOSE observer 的回归,证明它与 phase-only login 和 peer-close 共享同一 LoginPhase owner;不重新修复已闭合的 peer-close 生产逻辑,合同保持 PARTIAL。"}
{"time":"2026-09-21T12:59:08Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/phase-close-server-fixture"],"files":["extension/src/net/m2_client.cpp","project/app_flow_lifecycle_test.gd","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/remediation-roadmap.md","audit/history.jsonl"],"tests":["pre-fix godot --headless --path project --script app_flow_lifecycle_test.gd --quit-after 10 (FAIL: explicit PHASE_CLOSE does not synthesize transport disconnected)","post-fix godot --headless --path project --script app_flow_lifecycle_test.gd --quit-after 10 (PASS)","cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test mtgodot -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","godot --headless --path project --script p10_test.gd --quit-after 10 (PASS)","godot --headless --path project --script netplay_test.gd --quit-after 10 (PASS; exit 0)","godot --headless --path project --script disconnect_world_reset_test.gd --quit-after 10 (PASS)"],"reason":"按 40250 RecvPhasePacket(PHASE_CLOSE) -> ClosePhase -> SetLoginPhase 与 OnRemoteDisconnect 的分离语义,移除 M2Client::on_phase_close 对 classic_remote_disconnect_pending/disconnected 的伪造;显式 PHASE_CLOSE 改由 phase_changed(LoginPhase) 和已有 phase-leave world reset 接管,重入 LoginPhase 发送失败统一走 login_failed。真实服务端主动 PHASE_CLOSE 包序仍未取证,合同保持 PARTIAL。"}
{"time":"2026-09-21T12:59:08Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/phase-close-server-fixture"],"tests":["app_flow_lifecycle_test.gd pre-fix and post-fix regression (PASS after fix)","net_classic_session_test (PASS)","net_classic_stream_test (PASS)","net_loopback_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","p10_test.gd (PASS)","netplay_test.gd (exit 0)","disconnect_world_reset_test.gd (PASS)"],"reason":"显式 PHASE_CLOSE 的 transport-owner 分离、旧 world 清理和 LoginPhase owner 本地回归通过;本轮未宣称真实服务端主动 PHASE_CLOSE、空角色 live 或完整跨阶段 retry 已完成。"}
{"time":"2026-09-21T13:06:14Z","event":"implementation_hardening","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/empty-role-live-fixture"],"files":["extension/tools/net_classic_e2e.cpp","project/app_flow_lifecycle_test.gd","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/remediation-roadmap.md","audit/history.jsonl"],"tests":["pre-fix godot --headless --path project --script app_flow_lifecycle_test.gd --quit-after 10 (FAIL: live probe treats an all-empty character list as a valid SelectPhase result)","post-fix godot --headless --path project --script app_flow_lifecycle_test.gd --quit-after 10 (PASS)","build-debug/extension/net_classic_e2e with MT_CLASSIC_EXPECT_EMPTY=1 against current 40250 account (expected refusal: slot 0 occupied, exit 3)"],"reason":"按 40250 __RecvLoginSuccessPacket3/4 -> SetSelectPhase 的空槽语义,给 live e2e 探针增加 MT_CLASSIC_EXPECT_EMPTY=1;全空角色列表将被视为合法 SelectPhase 结果并立即结束,不发送过期选人包。当前 live 账号仅部分空槽,因此本轮没有伪造全空账号的正向证据。"}
{"time":"2026-09-21T13:06:14Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/empty-role-live-fixture"],"tests":["cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test net_classic_e2e mtgodot -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","ASAN_OPTIONS=detect_leaks=0 build-asan/extension/net_classic_session_test (PASS)","godot app_flow_lifecycle_test.gd (PASS)","godot p10_test.gd (PASS)","godot netplay_test.gd (PASS; exit 0)","godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","git diff --check (PASS)"],"reason":"本地全空 LOGIN_SUCCESS4、固定四槽、SELECT owner、半包/重复 phase 和 live probe 负向保护均通过;真实全空角色账号、服务器主动 PHASE_CLOSE 和完整跨阶段 retry 仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T14:02:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/login-form-retry-owner"],"files":["project/app_flow.gd","project/app_flow_lifecycle_test.gd","extension/src/net/m2_client.h","extension/src/net/m2_client.cpp","extension/src/net/classic/classic_session.h","extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/remediation-roadmap.md","audit/history.jsonl"],"tests":["pre-fix godot --headless --path project --script app_flow_lifecycle_test.gd --quit-after 10 (FAIL: login form retry replaces only the authentication transport; PRE_FIX_RC=1)","post-fix app_flow_lifecycle_test.gd (PASS)","post-fix net_classic_session_test LoginPhase retry loopback fixture (PASS)"],"reason":"按 40250 LoginWindow.Connect -> MainStream.Connect -> CAccountConnector::Connect 的 owner 语义,增加 AppFlow/M2Client/ClassicSession 的 retry_login 路径。登录失败、认证连接失败、认证 peer close 或游戏登录失败后,重试复用现有 session、只替换认证 transport,不再由登录表单重试触发 disconnect_from_server/world_reset;无待重试 owner 的首次连接仍回退到原完整连接入口。真实 Windows 可视化 retry 和真实服务器失败后重新输入成功的包序仍未取证,合同保持 PARTIAL。"}
{"time":"2026-09-21T14:14:00Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/login-form-retry-owner","network.login.phase_flow/auth-game-phase-matrix"],"tests":["cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test net_entity_test mtgodot net_classic_e2e -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","build-debug/extension/net_entity_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","ASAN_OPTIONS=detect_leaks=0 build-asan/extension/net_classic_session_test (PASS)","godot app_flow_lifecycle_test.gd (PASS)","godot p10_test.gd (PASS)","godot netplay_test.gd (exit 0)","godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS; no payload differences)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_ledger.py refresh --write (PASS; 32 fingerprints refreshed)","audit_ledger.py report --write (PASS)","audit_ledger.py validate (PASS; 45 contracts)","manifest.json/history.jsonl JSON validation (PASS)","git diff --check (PASS)"],"reason":"LoginPhase retry owner 的修复前失败、修复后 UI/native loopback 回归、native/CTest/ASAN/Godot 全量网络相关测试、阶段分派审计和账本校验均通过;真实 Windows 可视化重试、真实服务端失败后重新输入成功、空角色正向 live、服务器主动 PHASE_CLOSE live、完整重复进入/跨阶段重试包序和可选安全 runtime 仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T14:18:00Z","event":"implementation_hardening","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/login-form-retry-owner"],"files":["project/app_flow_lifecycle_test.gd","extension/src/net/m2_client.cpp","audit/history.jsonl"],"tests":["godot --headless --path project --script app_flow_lifecycle_test.gd --quit-after 10 (PASS; source guard verifies retry_login path calls ClassicSession::retry_login and does not call the global teardown)","git diff --check (PASS)"],"reason":"补充防回归源级断言,确保 retry_login 不是仅增加 API 名称而仍回退到全局连接/世界清理;不改变生产行为,合同保持 PARTIAL。"}
{"time":"2026-09-21T13:31:13Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/cross-phase-retry-order"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/remediation-roadmap.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix build-debug/extension/net_classic_session_test (FAIL: auth-success clears a pipelined stale PHASE_AUTH without a duplicate CG_LOGIN3)","reference source inspection (PASS: CAccountConnector::__AuthState_RecvAuthSuccess calls Disconnect/Clear before the next auth frame)","post-fix build-debug/extension/net_classic_session_test (PASS)"],"reason":"按 40250 __AuthState_RecvAuthSuccess -> Disconnect -> Clear 的旧 AccountConnector 边界,修复认证成功或拒绝结果后同一接收 burst 中迟到 PHASE_AUTH 仍被当前 ClassicStream 继续处理并重复发送 CG_LOGIN3 的差异;GC_LOGIN_FAILURE 仍保留原 AUTH owner 供显式 retry。游戏登录失败后的迟到 phase、完整跨阶段 UI retry、真实重复进入和 server PHASE_CLOSE live 仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T13:31:13Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/cross-phase-retry-order","network.login.phase_flow"],"tests":["pre-fix build-debug/extension/net_classic_session_test (FAIL: 1 check)","post-fix build-debug/extension/net_classic_session_test (PASS; auth-success stale phase tail is discarded)","audit ledger and full regression pending in this round"],"reason":"本轮先记录修复前/后的专项证据;待完成 native/CTest/ASAN/Godot、phase/packet audit、ledger refresh/report/validate 和 git diff --check 后补充最终测试记录,合同保持 PARTIAL。"}
{"time":"2026-09-21T13:35:27Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/cross-phase-retry-order","network.login.phase_flow"],"tests":["cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test net_entity_test mtgodot net_classic_e2e -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","build-debug/extension/net_entity_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","ASAN_OPTIONS=detect_leaks=0 build-asan/extension/net_classic_session_test (PASS)","godot app_flow_lifecycle_test.gd (PASS)","godot p10_test.gd (PASS)","godot netplay_test.gd (exit 0)","godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS; no payload differences)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","git diff --check (PASS)","audit_ledger.py refresh --write; report --write; validate (PASS; 45 contracts)","manifest.json/history.jsonl JSON validation (PASS)"],"reason":"认证成功后迟到 PHASE_AUTH 的修复专项、native/CTest/ASAN/Godot 回归、阶段分派审计和台账校验均通过;完整跨阶段 UI retry、游戏登录失败后的迟到 game phase、空角色正向 live、服务器主动 PHASE_CLOSE live、真实重复进入包序和可选安全 runtime 仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T13:43:39Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/cross-phase-retry-order-game-login-stale-tail"],"files":["extension/src/net/classic/classic_stream.h","extension/src/net/classic/classic_stream.cpp","extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/remediation-roadmap.md","audit/manifest.json","audit/reports/coverage.md","audit/history.jsonl"],"tests":["pre-fix build-debug/extension/net_classic_session_test (FAIL: LoginPhase stops after login failure before a pipelined PHASE_LOGIN; deferred PHASE_LOGIN is processed on the next tick)","reference source inspection (PASS: PythonNetworkStream LoginPhase/SelectPhase return after one application packet; Loading delegates game packets separately)","post-fix build-debug/extension/net_classic_session_test (PASS)"],"reason":"按 40250 phase-local handler 的单应用包返回边界,增加 ClassicStream return_after_current_packetLoginPhase、SelectPhase、DirectEnter Select owner 和 Loading 自有包保留迟到 receive tail 到下一次处理周期,避免游戏登录失败后同一 burst 立即重发 CG_LOGIN。Loading 转交 GamePhase 的游戏包未套用单包限制。"}
{"time":"2026-09-21T13:43:39Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/cross-phase-retry-order-game-login-stale-tail","network.login.phase_flow"],"tests":["cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test net_entity_test mtgodot net_classic_e2e -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","build-debug/extension/net_entity_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","ASAN_OPTIONS=detect_leaks=0 build-asan/extension/net_classic_session_test (PASS)","godot app_flow_lifecycle_test.gd (PASS)","godot p10_test.gd (PASS)","godot netplay_test.gd (exit 0)","godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS; no payload differences)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_ledger.py refresh --write; report --write; validate (PASS; 45 contracts)","manifest.json/history.jsonl JSON validation (PASS)","git diff --check (PASS)"],"reason":"本轮游戏 LoginPhase stale-tail 修复、完整 native/CTest/ASAN/Godot 回归、阶段/包结构审计和账本校验均通过;真实 Windows/服务端失败后重新输入成功、完整跨阶段 retry、空角色正向 live、服务器主动 PHASE_CLOSE live、真实重复进入包序和可选安全 runtime 仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T13:49:12Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/auth-connect-immediate-failure-owner"],"files":["extension/src/net/classic/classic_session.h","extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/remediation-roadmap.md","audit/manifest.json","audit/reports/coverage.md","audit/history.jsonl"],"tests":["pre-fix build-debug/extension/net_classic_session_test (FAIL: synchronous auth connect failure returns to the 40250 Offline owner; synchronous auth connect failure keeps the LoginPhase retry owner)","reference source inspection (PASS: CNetworkStream::Connect calls OnConnectFailure on immediate socket/connect errors; CAccountConnector then calls __OfflineState_Set)","post-fix build-debug/extension/net_classic_session_test (PASS)"],"reason":"按 40250 CAccountConnector::Connect -> CNetworkStream::Connect -> OnConnectFailure -> __OfflineState_Set 的调用链,统一认证同步地址/socket失败与异步连接失败的 owner 清理;当前客户端不再把同步认证失败直接置为 Failed,而是回到 Offline 并保留 LoginPhase retry owner。"}
{"time":"2026-09-21T13:49:12Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/auth-connect-immediate-failure-owner","network.login.phase_flow"],"tests":["cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test net_entity_test mtgodot net_classic_e2e -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","build-debug/extension/net_entity_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","ASAN_OPTIONS=detect_leaks=0 build-asan/extension/net_classic_session_test (PASS)","godot app_flow_lifecycle_test.gd (PASS)","godot p10_test.gd (PASS)","godot netplay_test.gd (exit 0)","godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS; no payload differences)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_ledger.py refresh --write; report --write; validate (PASS; 45 contracts)","manifest.json/history.jsonl JSON validation (PASS)","git diff --check (PASS)"],"reason":"本轮认证同步连接失败 owner 修复、完整 native/CTest/ASAN/Godot 回归、阶段/包结构审计和账本校验均通过;真实 Windows LoginWindow.OnConnectFailure 表现、服务端失败后重新输入成功、游戏连接同步失败 owner、完整跨阶段 retry、空角色正向 live、服务器主动 PHASE_CLOSE live、真实重复进入包序和可选安全 runtime 仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T14:04:01Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/game-connect-immediate-failure-owner"],"files":["extension/src/net/classic/classic_session.h","extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","extension/src/net/m2_client.cpp","project/app_flow.gd","project/login.gd","project/app_flow_lifecycle_test.gd","audit/contracts/network.login.phase-flow.md","audit/remediation-roadmap.md","audit/manifest.json","audit/reports/coverage.md","audit/history.jsonl"],"tests":["pre-fix build-debug/extension/net_classic_session_test (FAIL: DirectEnter connect failure follows OnConnectFailure -> ClosePhase; DirectEnter connect failure is not reported as credential login failure)","pre-fix build-debug/extension/net_classic_session_test (FAIL: ordinary game-connect failure is not reported as credential login failure)","reference source inspection (PASS: NetStream Clear -> CPythonNetworkStream::OnConnectFailure -> DirectEnter ClosePhase or LoginWindow.OnConnectFailure)","post-fix build-debug/extension/net_classic_session_test (PASS)"],"reason":"按 40250 的普通 LoginWindow.OnConnectFailure 与 DirectEnter ClosePhase 分支,统一同步/异步 game connect failure owner;新增独立 ClassicSession callback 和 M2Client connect_failed signal,禁止把游戏连接拒绝当作凭据错误,并移除 GC_WARP 失败桥接层伪造的 disconnected。真实 Windows UI 和失败后的 live 回退包序仍是未闭合证据。"}
{"time":"2026-09-21T14:04:01Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/game-connect-immediate-failure-owner","network.login.phase_flow"],"tests":["cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test net_entity_test mtgodot net_classic_e2e -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","build-debug/extension/net_entity_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","cmake --build build-asan --target net_classic_session_test -j4 (PASS)","ASAN_OPTIONS=detect_leaks=0 build-asan/extension/net_classic_session_test (PASS)","godot app_flow_lifecycle_test.gd (PASS)","godot p10_test.gd (PASS)","godot netplay_test.gd (exit 0)","godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS; no payload differences)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_ledger.py refresh --write; report --write; validate (PASS; 45 contracts)","manifest.json/history.jsonl JSON validation (PASS)","git diff --check (PASS)"],"reason":"DirectEnter、普通 auth-to-game、Godot connect_failed 和 GC_WARP owner 分离均有修复前失败与修复后回归证据;合同仍因真实 Windows OnConnectFailure 表现、初始认证 bridge、真实失败回退包序、空角色、PHASE_CLOSE live、完整 retry 和可选安全 runtime 保持 PARTIAL。"}
{"time":"2026-09-21T14:15:25Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/auth-connect-bridge-owner"],"files":["extension/src/net/classic/classic_session.h","extension/src/net/classic/classic_session.cpp","extension/src/net/m2_client.h","extension/src/net/m2_client.cpp","project/auth_connect_bridge_test.gd","audit/contracts/network.login.phase-flow.md","audit/remediation-roadmap.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix project/auth_connect_bridge_test.gd (FAIL: initial auth bridge and retry owner checks; 4 check(s) failed)","post-fix project/auth_connect_bridge_test.gd with MT_PROTOCOL=classic (PASS)","cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test net_entity_test mtgodot net_classic_e2e -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","build-debug/extension/net_entity_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","cmake --build build-asan --target net_classic_session_test -j4 (PASS)","ASAN_OPTIONS=detect_leaks=0 build-asan/extension/net_classic_session_test (PASS)","godot app_flow_lifecycle_test.gd (PASS)","godot p10_test.gd (PASS)","godot netplay_test.gd (exit 0)","godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS; no payload differences)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)"],"reason":"按 40250 CAccountConnector::OnConnectFailure -> Offline -> LoginWindow 的 owner 语义,新增 ClassicSession auth-connect-failure bridge 和 M2Client pending owner,认证同步/异步失败不再转换为 login_failed -> Failed,也不销毁 sessionretry_login 只替换认证 transport。真实 Windows LoginWindow 视觉表现、真实服务端失败后重新输入成功、服务器主动 PHASE_CLOSE live、完整跨阶段 retry 和可选安全 runtime 仍未取证,合同保持 PARTIAL。"}
{"time":"2026-09-21T14:26:03Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/auth-peer-close-bridge-owner"],"files":["extension/src/net/classic/classic_session.h","extension/src/net/classic/classic_session.cpp","extension/src/net/m2_client.h","extension/src/net/m2_client.cpp","project/auth_peer_close_bridge_test.gd","audit/contracts/network.login.phase-flow.md","audit/remediation-roadmap.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix project/auth_peer_close_bridge_test.gd (FAIL: auth peer close was reported as login_failed and entered failed; 2 check(s) failed)","post-fix project/auth_peer_close_bridge_test.gd with MT_PROTOCOL=classic (PASS: initial and retry auth peer close retain non-terminal owner)","post-fix project/auth_connect_bridge_test.gd with MT_PROTOCOL=classic (PASS)"],"reason":"按 40250 CAccountConnector::OnRemoteDisconnect -> __OfflineState_Set 的语义,增加独立 auth remote-disconnect callback 和 M2Client pending owner;认证 peer close 不再伪造 login_failed/connect_failed,且 retry_login 只替换认证 transport。合同仍保持 PARTIAL,真实 Windows/服务端 PHASE_CLOSE、完整 live retry 包序和可选安全 runtime 尚未取证。"}
{"time":"2026-09-21T14:26:04Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/auth-peer-close-bridge-owner","network.login.phase_flow"],"tests":["cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test net_entity_test mtgodot net_classic_e2e -j4 (PASS)","project/auth_peer_close_bridge_test.gd with MT_PROTOCOL=classic (PASS)","project/auth_connect_bridge_test.gd with MT_PROTOCOL=classic (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","build-debug/extension/net_entity_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","cmake --build build-asan --target net_classic_session_test -j4 (PASS)","ASAN_OPTIONS=detect_leaks=0 build-asan/extension/net_classic_session_test (PASS)","godot app_flow_lifecycle_test.gd (PASS)","godot p10_test.gd (PASS)","godot netplay_test.gd (exit 0)","godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS; no payload differences)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_source_coverage.py (PASS; 524 active files, 0 unowned behavior candidates)","audit_sequence_table.py (PASS; no sequence differences)","audit_ledger.py refresh --write (PASS)","audit_ledger.py report --write (PASS)","audit_ledger.py validate (PASS; 45 contracts)","manifest.json/history.jsonl JSON validation (PASS)","git diff --check (PASS)"],"reason":"认证 peer-close bridge 的修复前失败、修复后本地真实 TCP 回归、完整 native/CTest/ASAN/Godot 网络回归、阶段/包结构、源码覆盖和账本校验均通过;合同仍因真实 Windows/服务端 PHASE_CLOSE、空角色 live、完整跨阶段 retry、重复进入包序和可选安全 runtime 保持 PARTIAL。"}
{"time":"2026-09-21T14:42:16Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/phase-close-disconnect-login-owner"],"files":["extension/src/net/classic/classic_session.h","extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/remediation-roadmap.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix build-debug/extension/net_classic_session_test (FAIL: PHASE_CLOSE uses ClosePhase -> SetLoginPhase without sending CG_LOGIN on the closed stream)","reference source inspection (PASS: PHASE_LOGIN sends login; PHASE_CLOSE/OnRemoteDisconnect call Python SetLoginPhase -> net.Disconnect)","post-fix build-debug/extension/net_classic_session_test (PASS: LoginPhase owner, old transport Offline, no stale CG_LOGIN)","post-fix peer-close regression (PASS: no stale login packet; password retained until next LoginWindow.Connect as in reference Python path)"],"reason":"按 40250 拆分 native PHASE_LOGIN 与 Python ClosePhase/remote-disconnect 的同名 SetLoginPhase 语义;只有真正的 PHASE_LOGIN 在当前连接发送 CG_LOGIN/CG_LOGIN2PHASE_CLOSE、peer close 和 DirectEnter failure 先清理旧 transport 并回到 LoginWindow owner。真实 Windows UI、服务器主动 PHASE_CLOSE live 包序和完整失败重试仍未取证,合同保持 PARTIAL。"}
{"time":"2026-09-21T14:42:16Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/phase-close-disconnect-login-owner","network.login.phase_flow"],"tests":["cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test net_entity_test mtgodot net_classic_e2e -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","build-debug/extension/net_entity_test (PASS)","build-debug/extension/net_classic_e2e without args (EXPECTED USAGE EXIT 64; live evidence requires explicit credentials/endpoint)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","cmake --build build-asan --target net_classic_session_test -j4 (PASS)","ASAN_OPTIONS=detect_leaks=0 build-asan/extension/net_classic_session_test (PASS)","godot app_flow_lifecycle_test.gd (PASS)","godot p10_test.gd (PASS)","godot netplay_test.gd (PASS)","godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS; no payload differences)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_source_coverage.py (PASS; 524 active files, 0 unowned behavior candidates)","audit_sequence_table.py (PASS; no sequence differences)"],"reason":"本地 close/login owner 的修复前失败、修复后 native/CTest/ASAN/Godot 回归和四项结构审计均通过;合同继续保持 PARTIAL,因为真实 Windows LoginWindow 时序、服务器主动 PHASE_CLOSE、完整跨阶段 retry、GC_WARP 失败回退和可选安全 runtime 仍是未闭合证据。"}
{"time":"2026-09-21T14:57:56Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/game-peer-close-retry-owner"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/remediation-roadmap.md","audit/manifest.json","audit/reports/coverage.md","audit/history.jsonl"],"tests":["pre-fix build-debug/extension/net_classic_session_test (FAIL: in-game peer close keeps the LoginWindow retry owner on the same session; 1 check)","reference source inspection (PASS: CPythonNetworkStream::OnRemoteDisconnect -> networkmodule.SetLoginPhase -> net.Disconnect -> LoginWindow; LoginWindow.Connect -> ConnectToAccountServer replaces only the auth transport)","post-fix build-debug/extension/net_classic_session_test (PASS: same-session retry replaces auth transport and sends new CG_LOGIN3 with new password)"],"reason":"按 40250 的游戏 peer-close 后 LoginWindow retry owner 边界,修复 ClassicSession 在游戏连接被动断开后未设置 login_retry_pending 的差异;M2Client 现在可保留同一 session 并只替换认证 transport。真实 Windows UI、真实服务端失败后重试成功包序和完整跨阶段 retry 仍未取证,合同保持 PARTIAL。"}
{"time":"2026-09-21T14:57:56Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/login-failure-retry-cleanup/game-peer-close-retry-owner","network.login.phase_flow"],"tests":["cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test net_entity_test mtgodot net_classic_e2e -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","build-debug/extension/net_entity_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","cmake --build build-asan --target net_classic_session_test -j4 (PASS)","ASAN_OPTIONS=detect_leaks=0 build-asan/extension/net_classic_session_test (PASS)","godot app_flow_lifecycle_test.gd (PASS)","godot p10_test.gd (PASS)","godot netplay_test.gd (PASS)","godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS; no payload differences)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_source_coverage.py (PASS; 524 active files, 0 unowned behavior candidates)","audit_sequence_table.py (PASS; no sequence differences)","audit_ledger.py refresh --write (PASS; 45 contracts)","audit_ledger.py report --write (PASS)","audit_ledger.py validate (PASS)","manifest.json JSON validation (PASS)","git diff --check (PASS)"],"reason":"游戏态 peer-close retry owner 的 native loopback、全量 native/CTest/ASAN/Godot 回归、阶段/包结构审计和账本校验均通过;packet registry 仅保留已批准的 HDR_GC_SYMBOL_DATA 适配,真实 Windows/服务端 PHASE_CLOSE、完整 live retry、空角色正向 live、真实重复进入包序和可选安全 runtime 仍未闭合。"}
{"time":"2026-09-21T15:04:20Z","event":"live_evidence_refresh","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/live-package-order/server-initiated-phase-close","network.login.phase_flow/auth-game-phase-matrix/live-package-order","network.login.phase_flow/real-server-sequence"],"files":["project/live_smoke_test.gd","script/live_smoke_test.sh","audit/contracts/network.login.phase-flow.md","audit/remediation-roadmap.md","audit/manifest.json","audit/history.jsonl","../40250/Server Client TMP4/Server/metin2/src/server/game/src/cmd.cpp","../40250/Server Client TMP4/Server/metin2/src/server/game/src/cmd_general.cpp","../40250/Server Client TMP4/Server/metin2/src/server/game/src/desc.cpp"],"tests":["redacted Godot live smoke with MT_SMOKE_PHASE_COMMAND=/logout (PASS functional report: auth -> PHASE_GAME -> peer close -> world_reset -> LoginPhase owner)","redacted Godot live smoke with MT_SMOKE_PHASE_COMMAND=/logout and MT_NET_TRACE=1 (PASS functional report; no [classic:game] phase -> 0 / client-observable GC_PHASE(PHASE_CLOSE); peer close observed)","outer live_smoke_test.sh wrapper (FAIL only at existing 4 ParticlesShaderRD/RID leak gate; network functional report PASS)"],"reason":"40250 server source confirms logout -> SCMD_LOGOUT -> DESC::SetPhase(PHASE_CLOSE) state chain, but this build's DESC::Packet guard after m_iPhase=PHASE_CLOSE prevents an observable PHASE_CLOSE packet; the client trace therefore proves peer-close/LoginPhase-owner behavior only. No production client change is justified by this probe, and the server-initiated PHASE_CLOSE branch remains PARTIAL until a fixture that emits GC_PHASE(PHASE_CLOSE) is available; do not repeat the same /logout probe without changing the fixture."}
{"time":"2026-09-21T15:11:23Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/auth-success-game-before-auth-clear"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/remediation-roadmap.md","audit/manifest.json","audit/history.jsonl"],"tests":["pre-fix build-debug/extension/net_classic_session_test (FAIL: auth success starts game transport before clearing auth transport like 40250; 1 check)","reference source inspection (PASS: CAccountConnector::__AuthState_RecvAuthSuccess -> CPythonNetworkStream::Connect -> CAccountConnector::Disconnect)","post-fix build-debug/extension/net_classic_session_test (PASS: game:connecting -> auth:offline on loopback transports)"],"reason":"按 40250 认证成功的两个 transport owner 交接顺序,修复 ClassicSession::pump 先断开 auth 再连接 game 的差异;成功认证现在先启动主游戏 transport,再清理 AccountConnector transport。真实 Windows/服务端失败后重试、完整跨阶段 retry、空角色 live、服务器主动 PHASE_CLOSE live 和 DirectEnter/GC_WARP 失败回退仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T15:14:27Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/auth-success-game-before-auth-clear","network.login.phase_flow"],"tests":["cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test net_entity_test mtgodot net_classic_e2e -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","build-debug/extension/net_entity_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","cmake --build build-asan --target net_classic_session_test -j4 (PASS)","ASAN_OPTIONS=detect_leaks=0:halt_on_error=1 build-asan/extension/net_classic_session_test (PASS)","MT_PROTOCOL=classic godot app_flow_lifecycle_test.gd (PASS)","MT_PROTOCOL=classic godot auth_connect_bridge_test.gd (PASS)","MT_PROTOCOL=classic godot auth_peer_close_bridge_test.gd (PASS; exit 0)","MT_PROTOCOL=classic godot p10_test.gd (PASS)","MT_PROTOCOL=classic godot netplay_test.gd (PASS; exit 0)","MT_PROTOCOL=classic godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS; no payload differences)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_source_coverage.py (PASS; 524 active files, 0 unowned behavior candidates)","audit_sequence_table.py (PASS; matching 32768-entry sequence table)","audit_ledger.py refresh --write (PASS; 20 fingerprints refreshed)","audit_ledger.py report --write (PASS)","audit_ledger.py validate (PASS; 45 contracts)","manifest.json/history.jsonl JSON validation (PASS)","git diff --check (PASS)"],"reason":"认证成功 transport handoff 顺序的专项、完整 native/CTest/ASAN/Godot 网络阶段回归和四项结构审计均通过;packet registry 仍只有已批准的 HDR_GC_SYMBOL_DATA 适配。合同继续保持 PARTIAL,因为真实 Windows/服务端失败后重试成功、完整跨阶段 retry、空角色正向 live、服务器主动 PHASE_CLOSE live、DirectEnter/GC_WARP 失败回退和可选安全 runtime 仍未闭合。"}
{"time":"2026-09-21T15:28:30Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/game-login-retry-process-boundary"],"files":["extension/src/net/classic/classic_session.h","extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/remediation-roadmap.md","audit/manifest.json","audit/history.jsonl"],"tests":["reference source inspection (PASS: CPythonApplication::Process -> CPythonNetworkStream::Process -> CAccountConnector::Process; auth success starts main Connect after the main-stream turn)","pre-fix build-debug/extension/net_classic_session_test (FAIL: replacement PHASE_LOGIN was consumed in the auth-success frame; 1 check)","post-fix build-debug/extension/net_classic_session_test (PASS: replacement game transport is processed on the following pump)"],"reason":"按 40250 的主流先于 AccountConnector 的每帧处理顺序修复游戏 LoginPhase 重试边界;重试期间保留旧主流处理机会,认证成功建立替换游戏 transport 后跳过本帧新流处理,下一 pump 才消费 PHASE_LOGIN。真实 Windows LoginWindow、真实服务端失败后重试成功包序、完整跨阶段 retry、空角色 live、服务器主动 PHASE_CLOSE live 和 DirectEnter/GC_WARP 失败回退仍未取证,合同保持 PARTIAL。"}
{"time":"2026-09-21T15:31:23Z","event":"test_run","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/game-login-retry-process-boundary","network.login.phase_flow"],"tests":["cmake --build build-debug --target net_classic_session_test net_classic_stream_test net_loopback_test net_entity_test mtgodot net_classic_e2e -j4 (PASS)","build-debug/extension/net_classic_session_test (PASS)","build-debug/extension/net_classic_stream_test (PASS)","build-debug/extension/net_loopback_test (PASS)","build-debug/extension/net_entity_test (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","cmake --build build-asan --target net_classic_session_test -j4 (PASS)","ASAN_OPTIONS=detect_leaks=0:halt_on_error=1 build-asan/extension/net_classic_session_test (PASS)","MT_PROTOCOL=classic godot app_flow_lifecycle_test.gd (PASS)","MT_PROTOCOL=classic godot auth_connect_bridge_test.gd (PASS)","MT_PROTOCOL=classic godot auth_peer_close_bridge_test.gd (PASS; exit 0)","MT_PROTOCOL=classic godot p10_test.gd (PASS)","MT_PROTOCOL=classic godot netplay_test.gd (PASS; exit 0)","MT_PROTOCOL=classic godot disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS; no payload differences)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_source_coverage.py (PASS; 524 active files, 0 unowned behavior candidates)","audit_sequence_table.py (PASS; matching 32768-entry sequence table)","audit_ledger.py refresh --write (PASS; 20 changes written)","audit_ledger.py report --write (PASS)","audit_ledger.py validate (PASS; 45 contracts)","manifest.json/history.jsonl JSON validation (PASS)","git diff --check (PASS)"],"reason":"本地游戏 LoginPhase 重试处理帧边界的修复前失败与修复后专项、native/CTest/ASAN/Godot 网络回归和结构审计均通过;合同仍为 PARTIAL,因为真实 Windows/服务端失败后重试成功、完整跨阶段 retry、空角色正向 live、服务器主动 PHASE_CLOSE live、DirectEnter/GC_WARP 失败回退和可选安全 runtime 仍未闭合。"}
{"time":"2026-09-21T15:40:08Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/legacy-text-wire-encoding/ui-gb2312-input-capacity"],"files":["project/ui/char_select_screen.gd","project/char_create_delete_test.gd","extension/tests/net_text_codec_test.cpp","audit/contracts/network.login.phase-flow.md","audit/remediation-roadmap.md","audit/manifest.json","audit/history.jsonl"],"tests":["reference/source and current call-chain inspection (PASS: native ClassicSession already converts UTF-8 to GB2312 before fixed-field sends; CharSelectScreen still rejected valid GB2312-fitting names by UTF-8 byte count)","pre-fix code inspection (FAIL condition: target Chinese name would be rejected before create_character)","post-fix build-debug/extension/net_text_codec_test (PASS: target name is 27 UTF-8 bytes, 18 GB2312 bytes, 24-byte fit and round-trip)","post-fix build-debug/extension/net_classic_session_test (PASS)","post-fix MT_PROTOCOL=classic godot --headless --path project --script char_create_delete_test.gd (PASS)"],"reason":"按 40250 24-byte legacy character-field semantics,修复选人页把 UTF-8 输入字节数误当作 wire 容量的差异;UI 现在保留 UTF-8 内部文本并把 GB2312 可表示性/字节容量交给 native 发包边界,地图名、任务名、系统提示不套用角色名限制,合同仍保持 PARTIAL。"}
{"time":"2026-09-21T16:00:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/loading-enter-game-event-boundary"],"files":["extension/src/net/classic/classic_session.cpp","extension/src/net/classic/classic_session.h","extension/src/net/m2_client.cpp","extension/tools/net_classic_e2e.cpp","extension/tests/net_classic_session_test.cpp","docs/CLIENT-GAP-FIX.md","docs/CLIENT-GAP.md","audit/contracts/network.login.phase-flow.md","audit/manifest.json","audit/history.jsonl"],"tests":["reference source inspection (PASS: SetLoadingPhase -> LoadingPhase -> RecvMainCharacter -> GameWindow.LoadData -> SendEnterGamePacket -> SendEnterGame)","pre-fix build-debug/extension/net_classic_session_test (FAIL: GC_MAIN_CHARACTER did not trigger CG_ENTERGAME with the compatibility timer disabled; 1 check)","post-fix build-debug/extension/net_classic_session_test (PASS: GC_MAIN_CHARACTER sends CG_CLIENT_VERSION2 then one sequenced CG_ENTERGAME; duplicate main-character packets remain idempotent)","post-fix build-debug/extension/net_classic_stream_test (PASS)","post-fix build-debug/extension/net_loopback_test (PASS)","post-fix ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","post-fix ASAN_OPTIONS=detect_leaks=0:halt_on_error=1 build-asan/extension/net_classic_session_test (PASS)","post-fix MT_PROTOCOL=classic Godot app_flow_lifecycle_test.gd (PASS)","post-fix MT_PROTOCOL=classic Godot auth_connect_bridge_test.gd (PASS)","post-fix MT_PROTOCOL=classic Godot auth_peer_close_bridge_test.gd (PASS)","post-fix MT_PROTOCOL=classic Godot char_create_delete_test.gd (PASS)","post-fix MT_PROTOCOL=classic Godot p10_test.gd (PASS)","post-fix MT_PROTOCOL=classic Godot disconnect_world_reset_test.gd (PASS)","post-fix MT_PROTOCOL=classic Godot netplay_test.gd (PASS)","audit_phase_dispatch.py (PASS)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_sequence_table.py (PASS; matching 32768-entry sequence table)","audit_source_coverage.py (PASS; 524 active files, 0 unowned behavior candidates)","git diff --check (PASS)"],"reason":"按 40250 的 GC_MAIN_CHARACTER -> GameWindow.LoadData -> SendEnterGamePacket 事件边界,移除 ClassicSession 的 m_loading_since/m_entergame_delay 固定定时发送和 MT_CLASSIC_ENTER_DELAY 注入;主角/BGM 主角包解析并发送客户端版本后立即发送一次 CG_ENTERGAMEm_entergame_sent 保证重复包幂等。没有修改飞行物、技能、战斗或无关 UI。真实 Windows GameWindow 资源时序、真实服务端完整 Loading 包序、空角色正向 live、服务器主动 PHASE_CLOSE、完整跨阶段 retry/重复进入和可选安全 runtime 仍使合同保持 PARTIAL。"}
{"time":"2026-09-21T16:08:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/ticket-slot-warp-order/direct-enter-failure-login-owner-reset"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/remediation-roadmap.md","audit/manifest.json","audit/history.jsonl"],"tests":["40250 reference source inspection (PASS: OnConnectFailure -> ClosePhase -> networkmodule.SetLoginPhase -> net.Disconnect -> SetOffLinePhase -> __DirectEnterMode_Initialize)","pre-fix build-debug/extension/net_classic_session_test (FAIL: DirectEnter connect failure retained the stale slot through replacement PHASE_LOGIN; 1 check)","post-fix build-debug/extension/net_classic_session_test (PASS)","post-fix ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23 from the same repair round)","audit_ledger.py refresh --write/report --write/validate (PASS)","git diff --check (PASS)"],"reason":"按 40250 的 DirectEnter/GC_WARP 失败调用链,修复 ClosePhase/remote-disconnect owner 切换后残留 m_direct_enter 的差异;后续 replacement PHASE_LOGIN 进入普通 LoginPhase 并清理旧角色槽位。未修改飞行物、技能、战斗或 UI。真实 Windows/服务端失败回退包序、空角色 live、服务器主动 PHASE_CLOSE 和完整跨阶段 retry 仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T16:20:00Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/phase-close-login-retry-owner"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/remediation-roadmap.md","audit/manifest.json","audit/history.jsonl"],"tests":["40250 reference source inspection (PASS: PHASE_CLOSE -> ClosePhase -> networkmodule.SetLoginPhase -> net.Disconnect -> LoginWindow.Connect -> ConnectToAccountServer)","pre-fix build-debug/extension/net_classic_session_test (FAIL: PHASE_CLOSE did not retain a retry owner for replacement auth transport; 1 check)","post-fix build-debug/extension/net_classic_session_test (PASS: replacement auth transport and one CG_LOGIN3 after PHASE_AUTH)","post-fix ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","post-fix ASAN net_classic_session_test, Godot app_flow_lifecycle_test/p10_test/netplay_test/disconnect_world_reset_test (PASS)","audit_phase_dispatch.py (PASS), audit_packet_registry.py (PARTIAL only approved HDR_GC_SYMBOL_DATA), audit_sequence_table.py (PASS), audit_source_coverage.py (PASS)","audit_ledger.py refresh --write/report --write/validate and git diff --check (PASS)"],"reason":"按 40250 显式 PHASE_CLOSE 后 LoginWindow.Connect 的 retry owner 语义,设置 m_login_retry_pending,使同一 ClassicSession 只替换认证 transport并在新 PHASE_AUTH发送一份 CG_LOGIN3;未修改飞行物、技能、战斗或 UI。真实 Windows/服务端 PHASE_CLOSE、空角色 live、完整跨阶段 retry、GC_WARP失败回退和可选安全 runtime仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T16:25:49Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/phase-handshake-reentry-owner"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/remediation-roadmap.md","audit/manifest.json","audit/history.jsonl"],"tests":["40250 reference source inspection (PASS: RecvPhasePacket(PHASE_HANDSHAKE) -> SetHandShakePhase -> previous phase-leave; CAccountConnector::__AuthState_RecvPhase -> __HandshakeState_Set)","pre-fix build-debug/extension/net_classic_session_test (FAIL: game/auth owners ignored PHASE_HANDSHAKE and Game world cleanup; 3 checks)","post-fix build-debug/extension/net_classic_session_test (PASS)","cmake --build build-debug -j4 (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","ASAN_OPTIONS=detect_leaks=0:halt_on_error=1 build-asan/extension/net_classic_session_test (PASS)","MT_PROTOCOL=classic godot --headless --path project --script app_flow_lifecycle_test.gd (PASS)","MT_PROTOCOL=classic godot --headless --path project --script p10_test.gd (PASS)","MT_PROTOCOL=classic godot --headless --path project --script netplay_test.gd (PASS)","MT_PROTOCOL=classic godot --headless --path project --script disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_sequence_table.py (PASS; 32768 entries identical)","audit_source_coverage.py (PASS; 0 unowned behavior candidates)","audit_ledger.py refresh --write/report --write/validate (PASS; 45 contracts)","git diff --check (PASS)"],"reason":"按 40250 的 HandShake phase owner 重入语义,修复游戏/认证两条 PHASE_HANDSHAKE 分派;游戏从 Loading/Game 重入时先清理旧 world 并通知 phase-leave owner,后续等待新的 PHASE_LOGIN/PHASE_AUTH。未修改飞行物、技能、战斗或 UI;真实 Windows、服务器主动 PHASE_CLOSE、空角色 live、完整跨阶段 retry 和可选安全 runtime 仍使合同保持 PARTIAL。"}
{"time":"2026-09-21T16:37:18Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/auth-success-result-authority"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/remediation-roadmap.md","audit/manifest.json","audit/history.jsonl"],"tests":["40250 reference source inspection (PASS: CAccountConnector::__AuthState_RecvAuthSuccess branches only on bResult, then sets login key, connects game and disconnects AccountConnector)","pre-fix build-debug/extension/net_classic_session_test (FAIL: result=1 with login_key=0 was reported as BESAMEKEY; 1 check)","post-fix build-debug/extension/net_classic_session_test (PASS)","cmake --build build-debug -j4 (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","ASAN_OPTIONS=detect_leaks=0:halt_on_error=1 build-asan/extension/net_classic_session_test (PASS)","MT_PROTOCOL=classic godot --headless --path project --script app_flow_lifecycle_test.gd (PASS)","MT_PROTOCOL=classic godot --headless --path project --script p10_test.gd (PASS)","MT_PROTOCOL=classic godot --headless --path project --script netplay_test.gd (PASS)","MT_PROTOCOL=classic godot --headless --path project --script disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_sequence_table.py (PASS; 32768 entries identical)","audit_source_coverage.py (PASS; 0 unowned behavior candidates)","audit_ledger.py refresh --write/report --write/validate (PASS; 45 contracts)","manifest/history JSON validation (PASS)","git diff --check (PASS)"],"reason":"按 40250 的认证结果分支修复 login_key 非零约束:只有 result=0 触发 BESAMEKEYresult=1 即进入成功 handoff,票据值只作为后续 CG_LOGIN2 输入。未修改飞行物、技能、战斗或 UI;真实 Windows/服务器主动 PHASE_CLOSE、空角色 live、完整跨阶段 retry、GC_WARP 失败回退和可选安全 runtime仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T16:44:26Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/auth-phase-close-silent-owner"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/remediation-roadmap.md","audit/manifest.json","audit/history.jsonl","audit/reports/coverage.md"],"tests":["40250 reference source inspection (PASS: CAccountConnector::__AuthState_RecvPhase handles only PHASE_HANDSHAKE and PHASE_AUTH; PHASE_CLOSE falls through without changing AUTH owner)","pre-fix build-debug/extension/net_classic_session_test (FAIL: auth PHASE_CLOSE was reported as game phase closure/auth server closed phase; 1 check)","post-fix build-debug/extension/net_classic_session_test (PASS)","cmake --build build-debug -j4 (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","ASAN_OPTIONS=detect_leaks=0:halt_on_error=1 build-asan/extension/net_classic_session_test (PASS)","MT_PROTOCOL=classic godot --headless --path project --script app_flow_lifecycle_test.gd (PASS)","MT_PROTOCOL=classic godot --headless --path project --script p10_test.gd (PASS)","MT_PROTOCOL=classic godot --headless --path project --script netplay_test.gd (PASS)","MT_PROTOCOL=classic godot --headless --path project --script disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS; no payload differences)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_sequence_table.py (PASS; 32768 entries identical)","audit_source_coverage.py (PASS; 0 unowned behavior candidates)","audit_ledger.py refresh --write/report --write/validate (PASS; 45 contracts)","manifest/history JSON validation (PASS)","git diff --check (PASS)"],"reason":"按 40250 认证 phase 分派修复 auth PHASE_CLOSE 的错误语义:认证 close 不再设置游戏侧 phase_closed 或 auth server closed 错误,继续保留 AUTH owner,真实 socket disconnect/failure 才负责 Offline/失败迁移。未修改飞行物、技能、战斗、角色名编码或 UI;服务器主动 PHASE_CLOSE live 包序、空角色 live、完整跨阶段 retry、GC_WARP 失败回退和可选安全 runtime仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T16:56:06Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/phase-select-reentry-owner"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/remediation-roadmap.md","audit/manifest.json","audit/history.jsonl","audit/reports/coverage.md"],"tests":["40250 reference source inspection (PASS: PythonNetworkStreamPhaseSelect.cpp SetSelectPhase runs m_phaseLeaveFunc before installing SelectPhase; Game owner maps to __LeaveGamePhase)","pre-fix build-debug/extension/net_classic_session_test (FAIL: Game -> Select retained the old world and skipped phase-leave notification; 2 checks)","post-fix build-debug/extension/net_classic_session_test (PASS)","cmake --build build-debug -j4 (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","ASAN_OPTIONS=detect_leaks=0:halt_on_error=1 build-asan/extension/net_classic_session_test (PASS)","MT_PROTOCOL=classic godot --headless --path project --script app_flow_lifecycle_test.gd (PASS)","MT_PROTOCOL=classic godot --headless --path project --script p10_test.gd (PASS)","MT_PROTOCOL=classic godot --headless --path project --script netplay_test.gd (PASS)","MT_PROTOCOL=classic godot --headless --path project --script disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS; no payload differences)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_sequence_table.py (PASS; 32768 entries identical)","audit_source_coverage.py (PASS; 0 unowned behavior candidates)","audit_ledger.py refresh --write/report --write/validate (PASS; 45 contracts)","manifest/history JSON validation (PASS)","git diff --check (PASS)"],"reason":"按 40250 SetSelectPhase 的旧 phase-leave 语义,修复 Game -> Select 时旧 world 未清理、宿主未收到 phase-leave 的结构差异;只在 InGame owner 分支执行 reset_for_map_change/on_phase_leave,随后进入 Select/DirectEnter owner。未修改飞行物、技能、战斗、角色名编码或 UI;真实 Windows/服务器主动 PHASE_CLOSE、空角色 live、完整跨阶段 retry、GC_WARP 失败回退和可选安全 runtime仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T17:01:24Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/phase-dead-noop-time-sync"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/remediation-roadmap.md","audit/manifest.json","audit/history.jsonl","audit/reports/coverage.md"],"tests":["40250 reference source inspection (PASS: PythonNetworkStream.cpp RecvPhasePacket(PHASE_DEAD) has an explicit empty branch and returns true without a phase setter)","pre-fix build-debug/extension/net_classic_session_test (FAIL: PHASE_DEAD enabled time-sync and changed the next handshake response; 1 check)","post-fix build-debug/extension/net_classic_session_test (PASS)","cmake --build build-debug -j4 (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","ASAN_OPTIONS=detect_leaks=0:halt_on_error=1 build-asan/extension/net_classic_session_test (PASS)","MT_PROTOCOL=classic godot --headless --path project --script app_flow_lifecycle_test.gd (PASS)","MT_PROTOCOL=classic godot --headless --path project --script p10_test.gd (PASS)","MT_PROTOCOL=classic godot --headless --path project --script netplay_test.gd (PASS)","MT_PROTOCOL=classic godot --headless --path project --script disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS; no payload differences)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_sequence_table.py (PASS; 32768 entries identical)","audit_source_coverage.py (PASS; 0 unowned behavior candidates)","audit_ledger.py refresh --write/report --write/validate (PASS; 45 contracts)","manifest/history JSON validation (PASS)","git diff --check (PASS)"],"reason":"按 40250 RecvPhasePacket(PHASE_DEAD) 的空操作语义,移除当前端错误打开 time-sync mode 的副作用,保持重复握手使用普通 HANDSHAKE 回包。未修改飞行物、技能、战斗、角色名编码或 UI;真实 Windows/服务器主动 PHASE_CLOSE、空角色 live、完整跨阶段 retry、GC_WARP 失败回退和可选安全 runtime仍未闭合,合同保持 PARTIAL。"}
{"time":"2026-09-21T17:08:09Z","event":"implementation_fix_round","result":"PARTIAL","ids":["network.login.phase_flow/auth-game-phase-matrix/phase-dead-noop-time-sync"],"files":["extension/src/net/classic/classic_session.cpp","extension/tests/net_classic_session_test.cpp","audit/contracts/network.login.phase-flow.md","audit/remediation-roadmap.md","audit/manifest.json","audit/history.jsonl","audit/reports/coverage.md"],"tests":["40250 reference source inspection (PASS: PythonNetworkStream.cpp RecvPhasePacket(PHASE_DEAD) is an explicit empty branch; only real phase setters clear the close owner)","pre-fix build-debug/extension/net_classic_session_test (FAIL: PHASE_DEAD cleared the explicit PHASE_CLOSE owner marker; 1 check)","post-fix build-debug/extension/net_classic_session_test (PASS: plain HANDSHAKE response and PHASE_CLOSE marker are both preserved)","cmake --build build-debug -j4 (PASS)","ctest --test-dir build-debug --output-on-failure -j2 (PASS; 23/23)","ASAN_OPTIONS=detect_leaks=0:halt_on_error=1 build-asan/extension/net_classic_session_test (PASS)","MT_PROTOCOL=classic godot --headless --path project --script app_flow_lifecycle_test.gd (PASS)","MT_PROTOCOL=classic godot --headless --path project --script p10_test.gd (PASS)","MT_PROTOCOL=classic godot --headless --path project --script netplay_test.gd (PASS)","MT_PROTOCOL=classic godot --headless --path project --script disconnect_world_reset_test.gd (PASS)","audit_phase_dispatch.py (PASS; no payload differences)","audit_packet_registry.py (PARTIAL; only approved HDR_GC_SYMBOL_DATA adaptation)","audit_sequence_table.py (PASS; 32768 entries identical)","audit_source_coverage.py (PASS; 0 unowned behavior candidates)","audit_ledger.py refresh --write/report --write/validate (PASS; 45 contracts)","manifest/history JSON validation (PASS)","git diff --check (PASS)"],"reason":"在同一分支的进一步等价审计中补齐 PHASE_DEAD 的第二个无副作用约束:通用 phase != PHASE_CLOSE 条件会清除显式关闭 owner,修复为仅真实 phase setter 清除 m_phase_closed。此为同一稳定分支的实质性实现补充,不是重复修复。未修改飞行物、技能、战斗、角色名编码或 UI;真实 Windows/服务器主动 PHASE_CLOSE、空角色 live、完整跨阶段 retry、GC_WARP 失败回退和可选安全 runtime仍未闭合,合同保持 PARTIAL。"}
{"time": "2026-09-22T00:00:00Z", "event": "implementation_fix_round", "result": "PARTIAL", "ids": ["movement.keyboard.motion/camera-auto-follow-rotation"], "files": ["project/player_controller.gd", "project/keyboard_motion_timeline_test.gd", "audit/contracts/movement.keyboard-motion.md", "audit/remediation-roadmap.md", "audit/manifest.json", "audit/history.jsonl"], "tests": ["40250 reference source inspection (PASS: PythonPlayerInput.cpp:445-491 CPythonPlayer::NEW_MoveToDirection m_isCmrRot branch folds fDirRot to fSigDirRot/fRotRat and applies CCamera::Roll(-m_fCmrRotSpd*fElapsedTime*fRotRat/90) every frame a direction key is held and the movement gates pass)", "pre-fix keyboard_motion_timeline_test.gd (FAIL by construction: camera.yaw never written by _keyboard_wish/_process, new directional assertions would fail)", "post-fix godot --headless --path project --script keyboard_motion_timeline_test.gd (PASS)", "godot --headless --path project --script test_wasd_steering_parity.gd (PASS)", "godot --headless --path project --script test_no_auto_move_regression.gd (PASS)", "godot --headless --path project --script game_camera_test.gd (PASS)", "godot --headless --path project --script movement_parity_test.gd (PASS)", "godot --headless --path project --script player_move_test.gd (PASS)", "godot --headless --path project --script mouse_controller_test.gd (PASS)", "godot --headless --path project --script test_alignment_parity.gd (PASS)", "git diff --check (PASS)", "audit_ledger.py refresh --write/report --write/validate (PASS)", "cmake --build build-debug -j4 / ctest (BLOCKED: pre-existing stale CMakeCache.txt from a different checkout path, unrelated to this GDScript-only change; not run)", "godot --headless --path project --script player_motion_test.gd (BLOCKED: pre-existing parse error, GDScriptNativeClass.clear_texture_cache() not found in this Godot 4.7.1 build; file untouched this round, last changed in a prior commit)"], "reason": "按 40250 CPythonPlayer::NEW_MoveToDirection 的 m_isCmrRot 分支,在 player_controller.gd 新增 _camera_auto_rotate():按住方向键且通过 frozen/locked/private_shop_open/processing_emotion 门后,每帧按方向相对相机的方位角折算 fRotRat(正前/正后 0,正左右 ±90 最大速率,对角线减半),以 m_fCmrRotSpd=20.0 的速率持续把 camera.yaw 转向新朝向。D3D CCamera::Roll 与 Godot yaw 的转向手性相反,增量对 fRotRat 取正号(参考实现取负号),作为显式记录的平台适配,用『按住方向时相机朝该方向收敛、正前后不转、从不越界』的不变式核验,而非逐位对照 D3D 数值。未修改飞行物、技能、战斗、UI 或根运动/资源事件路径;Paralysis/Faint/Sleep 未接入移动门(新发现,记录于 Remaining,未修复)、根运动/AccumulationMovement、同步/受击门恢复顺序、真实模型姿态测试仍未闭合,合同保持 PARTIAL。"}
{"time": "2026-09-22T01:30:00Z", "event": "audit_round", "result": "PARTIAL", "ids": ["movement.keyboard.motion/canact-paralysis-faint-sleep-gate"], "files": ["audit/contracts/movement.keyboard-motion.md", "audit/manifest.json", "audit/history.jsonl"], "tests": ["40250 reference source reachability audit (exhaustive grep -arn across UserInterface/ + GameLib/ for SetParalysis/Paralysis, AFFECT_SLEEP/SetSleep, SetFaint/FaintTest, Stun/RecvStunPacket)"], "reason": "Investigated the movement.keyboard-motion.md Remaining item \"CActorInstance::CanAct() Paralysis/Faint/Sleep movement gates not wired into net_play.gd\" (flagged unfixed by the prior round). Findings: (1) IsParalysis()/m_isParalysis has exactly one setter in the whole reachable 40250 source, CInstanceBase::__Shaman_SetParalysis (InstanceBaseEffect.cpp:821-823), which itself has zero callers anywhere in the tree -- Paralysis is dead code, never true in live gameplay, so not wiring it is correct parity, not a gap. (2) IsSleep()/m_isSleep: the AFFECT_SLEEP case in SetAffect()s switch is commented out (dead); the only live setter is the AFFECT_STUN case (m_GraphicThingInstance.SetSleep(isVisible), ~InstanceBaseEffect.cpp:932-933) -- IsSleep() is functionally just an alias for AFFECT_STUN in practice, which the current clients Entity.stunned field already represents (entity_store.h:119) and net_play.gd::_can_process_network_state() already gates movement on (dead/stunned/knock_down) -- already covered, not a gap. (3) IsFaint()/m_isFaint: only setter is chrFaintTest() (PythonCharacterModule.cpp:1087-1105), a Python-bound debug helper (\"FaintTest\", registered alongside chrtestRestoreRenderMode) operating on GetSelectedInstancePtr(); the available 40250 checkout has no root/ Python UI/quest scripts to prove or disprove live-gameplay reachability -- evidence-blocked, left unresolved per SKILL.md do-not-audit-unreachable-code-as-product-behavior rule, no fix attempted. Byproduct finding while tracing IsStun(): CActorInstance::Stun() is only reachable via RecvStunPacket() (PythonNetworkStreamPhaseGame.cpp:1556-1578), which explicitly routes GC_STUN to Die() for the main character and to Stun() only for remote actors; verified this does NOT create a movement.keyboard.motion discrepancy because CanAct() blocks movement identically on IsDead() and IsStun(), and net_play.gd::_can_process_network_state() already blocks movement identically on dead and stunned -- the movement-blocking outcome is already correct parity regardless of which reference path fires. The Die()-vs-Stun() distinction only affects death-system semantics (m_isRealDead, EXP drop, corpse/respawn flow), which is combat.death.exp_drop/combat.affect_status territory and is already tracked there (combat.affect-status.md Remaining #2, equivalence rows 63/67: native GC_STUN only sets stunned=true with no dedicated clear path) -- not re-logged as a new finding to avoid duplicate tracking. No code changed this round; removed the resolved Remaining bullet from manifest.json and movement.keyboard-motion.md, replaced with investigation evidence and citations. Contract stays PARTIAL (root-motion/resource-event-source/sync-hit-death-gate-stacking/real-model-bone-flip items remain open)."}
{"time": "2026-09-22T03:15:00Z", "event": "implementation_fix_round", "result": "PARTIAL", "ids": ["movement.keyboard.motion/server-speed-scale-clamp"], "files": ["project/player_controller.gd", "project/keyboard_motion_timeline_test.gd", "audit/contracts/movement.keyboard-motion.md", "audit/manifest.json", "audit/history.jsonl", "audit/remediation-roadmap.md", "audit/reports/coverage.md"], "tests": ["40250 reference source inspection (PASS: InstanceBaseMovement.cpp CInstanceBase::SetMoveSpeed(UINT uMovSpd) only guards uMovSpd>1100 -> 0; otherwise applies uMovSpd/100.0f unclamped)", "extension/src/net/entity_store.cpp EntityStore::motion_move_speed re-read (PASS: already-fixed remote-entity path mirrors the same >1100 -> 0 / mount_vnum!=0 -> 0 guards, no [0.25,3.0]-style band)", "pre-fix player_controller.gd::set_server_speed (FAIL by construction: clampf(moving_speed/100.0, 0.25, 3.0) silently floors/ceils haste or slow stacks outside the reference's 25..300 movSpd band)", "post-fix godot --headless --path project --script keyboard_motion_timeline_test.gd (PASS, incl. new set_server_speed(10/500/1200/100) assertions)", "godot --headless --path project --script test_wasd_steering_parity.gd (PASS)", "godot --headless --path project --script test_no_auto_move_regression.gd (PASS)", "godot --headless --path project --script game_camera_test.gd (PASS)", "godot --headless --path project --script movement_parity_test.gd (PASS)", "godot --headless --path project --script player_move_test.gd (PASS)", "godot --headless --path project --script mouse_controller_test.gd (PASS)", "godot --headless --path project --script test_alignment_parity.gd (PASS)", "godot --headless --path project --script netplay_test.gd (PASS; unrelated mock set_server_speed in netplay_test.gd has no clamp, unaffected)", "git diff --check (PASS)", "audit_ledger.py refresh --write/report --write/validate (PASS)"], "reason": "在同一合同下追查『根运动 vs 连续速度』假设时发现这是假线索——entity_store.cpp::advance_walk_by_motion 与本地 _process() 的位移积分在种类上同构(都是恒速直线插值);真正的差异是 set_server_speed() 把 moving_speed/100.0 塞进无参考依据的 clampf(0.25, 3.0),而参考实现 CInstanceBase::SetMoveSpeed 和本项目已修复的 EntityStore::motion_move_speed 都只有 moving_speed>1100 -> 0 这一个门。移除该私有夹钳,改为 0.0 if moving_speed > 1100 else moving_speed/100.0,两处调用方(net_world.gd、net_play.gd)均不额外夹钳,改动范围限于 player_controller.gd。新增回归断言覆盖旧边界内外和 1100 冻结门。副产品发现:CInstanceBase::SHORSE::SetMoveSpeed 是坐骑上玩家的独立速度设定,只在 IsMounting() 时生效,与远端 mount_vnum!=0 -> 0 的处理方式不同——本轮未下定论,留作独立候选。未修改根运动/AccumulationMovement 适配层、资源与网络事件完整顺序、同步/受击门叠加或真实模型测试,合同保持 PARTIAL。"}