diff --git a/AGENTS.md b/AGENTS.md index f4549c3d..38630876 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -16,7 +16,7 @@ ## 运行与验证(工作目录 = 含 project.godot 的切片目录) -- **合回验证 = 远端 CI(2026-11-03 用户裁,取代 2026-10-30 本地 CI)**:git merge 合回 master 落地后,post-merge 钩子(`tools/hooks/post-merge`)自动 `git push origin master` 触发远端 CI(Gitea Actions,runner=Mac 本机 host 模式,环境自举件=`tools/ci/mac_setup.sh`),工作流(`.gitea/workflows/ci.yml`)按改动域分流(分流算法单点=`tools/ci/domain_route.sh`):游戏码批=两域全量含渲染闸,文档批=文档域秒级闸,纯闸件/管线批=零触发。远端结果**按需现查**:`tools/ci_check.sh <合并提交>` 读该提交任务的 run `status`/`conclusion`,只呈报、不落盘(2026-11-04 用户裁:合回不等待、不唤醒;判据只认 run 落定后的终局态,细则=process-conventions §1 第 3 条)。**合回落地即向用户呈报本批总结并止回合**,禁前台 sleep/轮询等 CI。CI 红态不回滚合并——红项在案、修复批合回即再推再验追绿;开工先跑现查件读 CI 状态,红未修不开新批。同一份字节禁止第二次人手跑。`tools/run_all_gates.sh` 仍是全部验证闸的**唯一入口与唯一清单,域划分与选闸算法只写在它这一个地方**,文档禁另列清单;`--code`/`--docs`/`--quick` 手动档只服务开发期按域跑批(开发期窄测纪律见 process-conventions §6),不构成验收;全量回归由用户自发发起。**runner 依赖**:Mac 需开机在线(关机=远端任务排队延后);换机/重装按 `tools/ci/mac_setup.sh` 自举 +- **合回验证 = 远端 CI(2026-11-03 用户裁,取代 2026-10-30 本地 CI)**:git merge 合回 master 落地后,post-merge 钩子(`tools/hooks/post-merge`)自动 `git push origin master` 触发远端 CI(Gitea Actions,runner=Mac 本机 host 模式,环境自举件=`tools/ci/mac_setup.sh`),工作流(`.gitea/workflows/ci.yml`)按改动域分流(分流算法单点=`tools/ci/domain_route.sh`):游戏码批=两域全量含渲染闸,文档批=文档域秒级闸,纯闸件/管线批=零触发。远端结果**按需现查**:`tools/ci_check.sh <合并提交>` 读该提交任务的 run `status`/`conclusion`,只呈报、不落盘(2026-11-04 用户裁:合回不等待、不唤醒;判据=run 落定后的终局态,且绿须坐实跑闸步真跑过——零触发批呈报「未验」不作绿证,细则=process-conventions §1 第 3 条)。**合回落地即向用户呈报本批总结并止回合**,禁前台 sleep/轮询等 CI。CI 红态不回滚合并——红项在案、修复批合回即再推再验追绿;开工先跑现查件读 CI 状态,红未修不开新批。同一份字节禁止第二次人手跑。`tools/run_all_gates.sh` 仍是全部验证闸的**唯一入口与唯一清单,域划分与选闸算法只写在它这一个地方**,文档禁另列清单;`--code`/`--docs`/`--quick` 手动档只服务开发期按域跑批(开发期窄测纪律见 process-conventions §6),不构成验收;全量回归由用户自发发起。**runner 依赖**:Mac 需开机在线(关机=远端任务排队延后);换机/重装按 `tools/ci/mac_setup.sh` 自举 - 单件直跑(调试期最窄确认用,**不构成验收**):冒烟测试 `python tools/run_smoke.py`(`game/tests/smoke_boot.tscn` 极小启动场景)· 系统测试 `python tools/run_system_test.py`(宿主 `game/tests/system_test.gd`)· 场景探针 `…console.exe --headless --path . res://probe/ui_probe.tscn` · 单元与集成 `… --script res://tests/run_all.gd` - 调参批量:`--script res://sim/adventure_monte_carlo.gd`(全冒险期望)· `res://sim/reward_expectation.gd`(奖励期望);关卡完成率/难度类测量一律走全冒险 - 数值验证:`python tools/balance_verifier.py`(采集端 `res://sim/verifier_batch.gd`,报告与原始数据落 `sim-data/`) diff --git a/design/engineering/architecture/architecture.md b/design/engineering/architecture/architecture.md index 087faa46..cbc0a6ce 100644 --- a/design/engineering/architecture/architecture.md +++ b/design/engineering/architecture/architecture.md @@ -86,7 +86,7 @@ | 模块 | 独占职责 | 对外暴露 | 消费依赖 | 引擎 API | |---|---|---|---|---| | **ConfigDB**(autoload,D2) | 全部玩法数值表与表现层布局配置表(`data/tables/*.tres` + `data/schemas/*.gd`);加载/校验/override/诊断状态机。**行族访问器归位各 schema 表类(表管自己的行查询),本类只留加载/校验/override/诊断门面;表持有成员按域收进四张域容器 Resource(`config_domain_combat/run/crossrun/presentation.gd`——前三件迭代 41 已建件,第四件表现层布局域 2026-10-30 建件,类型化成员 7/7/5/1);三张 resolver 表(board_gen.resolve_row/enemy.resolve_rowset/difficulty.resolve_modifiers)经 `load_tables` 装配段注入各容器,resolver 文件与键零搬移**——红线不变:本类仍是唯一加载与持有单点,"经 ConfigDB 单点读取"=经其持有的表对象 | 类型化域容器属性(每域一张容器);公开面 8(push_diag/is_fatal/reset_diagnostics/diagnostics/diagnostics_count/load_tables/set_reload_gate/reload)、类变量 10 | 无(基础层顶点) | Resource/.tres 加载、autoload 生命周期——LOW | -| **SlotStore**(`core/slot_store.gd`,D3 存档槽位域件,已建件——迭代 41 存量债批) | 存档三槽位文件域唯一所有者(自 save_manager 收编槽位族):槽位挂载与模板、激活与建删、槽位摘要窥视(peek 族);改名覆盖原语(_rename_overwrite)留 save_manager(IO 原语单点) | 槽位读写原语族+摘要投影(公开 10/类变量 4;SaveManager 与菜单消费方经 `save.slots.` 直连) | save_manager(注入路径与模板配置);FileAccess——LOW | +| **SlotStore**(`core/slot_store.gd`,D3 存档槽位域件,已建件——迭代 41 存量债批) | 存档三槽位文件域唯一所有者(自 save_manager 收编槽位族):槽位挂载与模板、激活与建删、槽位摘要窥视(peek 族);改名覆盖原语(_rename_overwrite)留 save_manager(IO 原语单点) | 槽位读写原语族+摘要投影(公开 10→11——+active_path 读投影、migrate_legacy_save 公开化;对 SaveManagerCore 反向私取 21 处清零=双向公开面;类变量 4;SaveManager 与菜单消费方经 `save.slots.` 直连) | save_manager(注入路径与模板配置);FileAccess——LOW | | **MetaStateStore**(`core/meta_state_store.gd`,D3 存档内元进度数据件,已建件——迭代 41 存量债批) | 存档内元进度数据的读写唯一层(自 save_manager 收编 accessor 族:钥石/道具解锁/树节点与叉侧/锻造路线/同调/真视/计数器/摘要——数据读写原语,不含业务规则);save_manager 与 meta_progression 双 God Class 的共同病根=该数据域摊在两文件,本件即其归一 | 写口原语 13+只读投影 6(tree_state/forge_state/attune_state/career_state 四投影+keystone_balance/item_unlocked)=公开 19(add_keystone 私有 `_add_keystone`),零 _data 副本零缓存;MetaProgression 业务层与营地/锻造 UI 消费方经 `save.meta_state.` 直连(meta 的纯转发读方法已退役) | save_manager(序列化接线);FileAccess——LOW | | **MetaProgression**(autoload,`core/meta_progression.gd`,D3 元进度业务层) | 元进度账本服务:钥石收束入账、营地消费定价与秘宝解锁判定的纯被动服务,零信号零外发;数据读写全经注入的 MetaStateStore(`save.meta_state.` 直连);hero_override() 现算不写表(全零=白板合法态——生效注入只走冒险开始参数面显式传参) | 写口族(天赋树购买/叉侧切换/锻造解锁与升级与选中/同调装配切换等)+解锁判定与读投影;**构造双形态**=autoload 装配走 `.new()` 零参+`_ready` 从 autoload 链取依赖(工程序 ConfigDB→RngService→SaveManager→MetaProgression,注册顺序即依赖序),单测/工具走 `.new(db, save)` 直构形态(不入树零 _ready)——**四个 Autoload 中唯一有跨 Autoload 依赖的件(ConfigDB/SaveManager)** | ConfigDB(定价与档位表值);SaveManager(存档访问器,经节点路径延迟取用) | autoload 生命周期——LOW | | **RngService**(autoload,D2) | master_seed、各流 scope 计数器(封闭流词表现值以 `RngServiceCore.PURPOSE_TAGS` 为准;增流走 P1 评审) | `set_master_seed()`(唯一调用方 C2);`open_stream(stream)` 有状态门面;`derive_at(stream, scope)` 纯函数;只读计数器 | ConfigDB(无) | 无——纯逻辑 | @@ -94,7 +94,7 @@ | **variation 定义**(A4) | VariationTable schema(现行 6 行:六 region——贫矿脉 global 行 2026-10-16 用户令屏蔽删行,global 型机制代码保留)与 F1 候选池门控谓词 | `variant_pool(level_index, board_type, node_type="")`(门控三维:unlock+board_types+节点身份——global 行仅 boss/elite 入池,缺省跳过零扰动);`global_variant_row(level_index, board_type, node_type)`(全局型单行决议访问器) | ConfigDB(VariationTable) | 无 | | **status_container**(B3) | 状态实例容器(战斗域生命周期、跨轮跨图延续) | 5 API:notify_battle_start / apply_effect / query_active / decay_round / notify_battle_end | ConfigDB(StatusEffectTable) | 无(RefCounted) | | **effect_engine**(内容数据驱动扩展批 iter17 建域) | 零运行时可变状态的系统(见「架构原则」条 8):全同步解释器——事件由宿主在明确代码点位显式调 dispatch 进件,命中序=装载声明序(feats→treasure→树规则)写死保种子复放,不是事件总线/事件循环;事件/事实/效果类型/算子四词表封闭 + 树规则合成订阅六键(posture 每关首轮窗/sense 两组限次 counter 闸·adv_ 前缀走冒险桶跨战斗持久) | rebuild(每战重建订阅表)/`dispatch(ctx, event, payload, facts)`/`validate_trigger_row` + 静态计数口 `counter`·`counter_add`·`counter_spend`·`bucket_of`·`counter_id_legal`(计数器读写只经 EffectContext 引用束,无导出/灌入接口) | ConfigDB(feats/treasure 行集)、EffectContext(四桶引用由宿主持有:round/battle 桶归编排器、level 桶归关卡域、adventure 桶归应用层——RunLedger 已随迭代 39 拆件批退役,桶字典由 adventure_runner 持有) | 无(零随机全确定) | -| **save_system**(D3,Alpha;iter27 已升格 autoload「SaveManager」) | 存档格式与版本比较 | (契约规范源:`../../gdd/systems/表现与支撑/存档序列化.md`——契约锚:SAVE_FORMAT_VERSION + master_seed + 各流 scope 计数器快照,须在无正在执行中的 open_stream 实例时切出) | ConfigDB、RngService 只读计数器 | FileAccess——LOW | +| **save_system**(D3,Alpha;iter27 已升格 autoload「SaveManager」) | 存档格式与版本比较 | save_manager 公开面 7→14(+set_read_only/read_only/reset_to_default/data_snapshot/restore_data 五承接方法+peek_summary_at/rename_overwrite 两更名公开化);(契约规范源:`../../gdd/systems/表现与支撑/存档序列化.md`——契约锚:SAVE_FORMAT_VERSION + master_seed + 各流 scope 计数器快照,须在无正在执行中的 open_stream 实例时切出) | ConfigDB、RngService 只读计数器 | FileAccess——LOW | | **settings/localization**(D6,愿景) | 设置项、翻译数据 | (契约规范源:`../../gdd/systems/表现与支撑/设置与本地化.md`) | ConfigDB | 无 | ### 核心层 @@ -102,7 +102,7 @@ | 模块 | 独占职责 | 对外暴露 | 消费依赖 | 引擎 API | |---|---|---|---|---| | **board_generator**(A1) | 生成算法(五阶段管线)、BoardGenTable 回填、生成期指标集、合法性谓词(clearable / R₀≠S / min_safe)、可推理率度量(metric_version);生成姿态 = MVP 同步生成 + 加载幕(切片实证 10×10/12×12 同步可接受,WorkerThread 留扩展) | `generate(L, D, rng) -> Board`;度量独立入口×3(推理器 / F3 度量 / 合法性谓词——独立纯函数、同一实现) | ConfigDB(BoardGenTable/VariationTable);board_gen 流(一次 open_stream = 一张图);dig_ap_cost 只读 | 无 | -| **minesweeper_rules**(A2) | 棋盘状态(已开集 O / 封印集 G / 小人位)、三事件面、批次仲裁、install 四不变式 | `install_board(board)`;`settle_batch(intents)`(唯一提交入口);查询只读面(current_board / hero_pos / is_revealed / has_seal 等);`compute_move_path(cell)` 只读;`preview_reveal(cell)` 只读预览口(零写入零事件——0 格连锁传播闭包;迭代 50 己案建口);`retire_board()`;三源拒绝(board_face / resource_face / phase)+ sub_reason 封闭枚举 | A1 产物(Board class_name 数据契约);A3 try_spend / last_round_end(迭代 41 由属性改方法)/ 相位 | 无(零表读取、零 UI——切片实证) | +| **minesweeper_rules**(A2) | 棋盘状态(已开集 O / 封印集 G / 小人位)、三事件面、批次仲裁、install 四不变式 | `install_board(board)`;`settle_batch(intents)`(唯一提交入口);查询只读面(current_board / hero_pos / is_revealed / has_seal 等);`compute_move_path(cell)` 只读;`preview_reveal(cell)` 只读预览口(零写入零事件——0 格连锁传播闭包;迭代 50 己案建口);`retire_board()`;+harmful_variants/harmful_adjacent 两有害判定面(自编排器归位);三源拒绝(board_face / resource_face / phase)+ sub_reason 封闭枚举;公开方法面 19→21(超阈值贴顶——还债归待办清单 P0 条目「minesweeper_rules 公开面还债」) | A1 产物(Board class_name 数据契约);A3 try_spend / last_round_end(迭代 41 由属性改方法)/ 相位 | 无(零表读取、零 UI——切片实证) | | **unit_container**(B2) | hero/enemy 单位实例(hp/atk/实例池:池快照+冷却+摇定动作+保底计数)、行值快照 | spawn / query_alive / rollable_skills / special_skills / check_trigger_unlocks / set_pending_action / pending_action / basic_streak / commit_action / tick_cooldowns / apply_damage / heal / default_target / check_skill_unlocks / despawn_all(2026-09-16 敌人技能池批:query_beat/query_attack/advance 随行为环退役;rollable_skills/special_skills/check_trigger_unlocks 带 facts 参——2026-10-27 情境条件触发器实装,事实缺键=条件假拦下,百分比事实走阈值式折算) | ConfigDB(EnemyTable/SkillTable/HeroTable) | 无 | | **reward_economy**(B4) | 格面资源身份映射(install 期预分配、Ready 只读、换图映射消亡)、极性路由字典面((类型, 极性)→ 字典行查询;路由执行归 B1 授予段)、F6 当量供给投影;装配期摇号面已拆出掷格件 RewardRoller(2026-11-02 轴戊设计闭合、迭代 49 卡① 建件——roll_board 装配序=守卫→复位→委托→收纳→ready;受理账面留守) | 封闭 API:roll_board / query_identity / query_full_snapshot / grant / grant_clear / retire_mapping / polarity_row / phase(weighted_pick 退役——返行选行算子迁掷格件);另有 is_mapped 静默布尔投影(批量工具用);实测类变量 11 | ConfigDB(RewardTable);BattleFxHost 经注入 Callable `luck_bias_query` 取偏运合计(reward_roll 发射与 bias_rewards 求和移至效果层完成);reward_roll 流(scope = 每次 install 批,取号经掷格件) | 无 | | **helper_items**(A5,切片已实装秘宝域) | HelperItemTable、探测显影语义 | (契约规范源:`../../gdd/systems/跨局循环/秘宝.md`——桥接位:A2 查询接口 + A4 counter_item_ids) | A2 / A4 / B4 | 无 | @@ -114,21 +114,21 @@ | **RefreshBank**(`core/refresh_bank.gd`,刷新账件,已实装(2026-10-27 迭代 39 拆件批)) | 三选一刷新三源账唯一所有者:X 刷新件每碰三选一重给(优先消耗不结转)/Y 营地升级行冒险周期池(用完即无)/刷新券存量账(冒险级跨停点持久)+GP 付费刷计数与报价公式;零停点态依赖(免费/付费支出的编排归 CurioStop,本件只记账) | 支出与余量原语+报价公式;断点自交片段(refresh_stock/attune_refresh_y 两键,Y 缺键回退参数面) | ConfigDB(刷新件与营地升级行表值);注入 CurioStop 支出路径 | 无(RefCounted 纯逻辑) | | **AttuneLoadout**(`core/attune_loadout.gd`,同调配装件,已实装(2026-10-27 迭代 39 拆件批)) | 装备中的秘宝件对象集唯一所有者(每件内含充能单位与重置周期);同调充能的物化行为唯一事实源——种行/补行改写时同步(RunLedger 充能字典轨与差额对账函数退役);旧档 aux_items 同调行迁移归件 | 构造注入;充能查询/消耗/按周期重置原语;断点自交片段(attunement_charges 键,键名与策略不变) | ConfigDB(秘宝行集);TreasureItems(同调行投放面);注入战斗使用路径 | 无 | | **CurioStop**(`core/curio_stop.gd`,三选一停点件,已实装(2026-10-27 迭代 39 拆件批)) | 三选一停点编排唯一所有者(架构原则 9 本域承载):停点三态(关卡完成三选一在途/已兑付待推进/奖励节点三选一在途)、刷新编排(三源账面归 RefreshBank 件、查停点态→支出→重抽重发编排留本件)、兑付方法族(pick/refresh/redeem/skip)、凭证出箱(RAP/时沙待注入);三选一信号面自带;零自动推进停点语义承载 | 对外=开停点/刷新/兑付/放行谓词/交断点片段五组入口+信号面(curio_choice_presented/curio_resolved);由 AdventureRunner 关卡完成受理时调用 | ConfigDB;注入 CurioDeck(抽签/摘牌)、HeroStats 与 GainJournal(兑付落账单写原语)、RefreshBank(刷新支出);随机只经 CurioDeck 的 reward_pick 封闭流 | 无 | -| **breakpoint_store**(`core/breakpoint_store.gd`,冒险域·断点组装与回放件,已建件——迭代 45) | 存档断点组装与回放唯一承载(自 adventure_runner 收编 6 成员+函数族):断点快照拼盘、回放回填、读侧策略分发;`BREAKPOINT_FIELDS` 27 键登记单源随件(键名/策略标签/键序冻结) | 构造=引用束注入(九引用束成员解包为原名成员——保迁移函数体逐字);`resume_adventure` 留宿主(壳+宿主侧回填语句——R2 所有权缝分家);断点键面零变化;实测类变量 15(贴顶禁再增) | adventure_runner(宿主);注入主角账三件与 curio/stop/bank/loadout 引用 | 无(RefCounted 纯逻辑) | +| **breakpoint_store**(`core/breakpoint_store.gd`,冒险域·断点组装与回放件,已建件——迭代 45) | 存档断点组装与回放唯一承载(自 adventure_runner 收编 6 成员+函数族):断点快照拼盘、回放回填、读侧策略分发;`BREAKPOINT_FIELDS` 27 键登记单源随件(键名/策略标签/键序冻结) | 构造=引用束注入(九引用束成员解包为原名成员——保迁移函数体逐字);`resume_adventure` 留宿主(壳+宿主侧回填语句——R2 所有权缝分家);断点键面零变化;公开方法面 5→18(13 新面承接 adventure_runner 私取清零+bp_read 公开化);实测类变量 15(贴顶禁再增) | adventure_runner(宿主);注入主角账三件与 curio/stop/bank/loadout 引用 | 无(RefCounted 纯逻辑) | ### 功能层 | 模块 | 独占职责 | 对外暴露 | 消费依赖 | 引擎 API | |---|---|---|---|---| | **battle_orchestrator**(B1) | 段序骨架(七段结构冻结)、轮 facts 缓冲、可回放步骤流、[明细行协议](../../gdd/systems/战斗循环/战斗结算.md#明细流水每一行都能指回你刚才的哪一步棋)(基础行型+扩展行两层 + 字段分层,词表以 owner「明细流水」节为准)、条款③⑤闭合对账、**战斗域全部跨系统调用权**、效果引擎宿主面与树规则挂点施加面(**已拆出 BattleFxHost 并实装(2026-10-28 迭代 40——battle_fx_host.gd/reward_grant.gd 两件在库,效果引擎宿主面归 BattleFxHost 行承载,拆件细则见「战斗编排域拆件定稿」节);2026-10-29 零豁免裁设计闭合:RoundCycle/BattleFacts 两新件随批(宿主 38→15、S13 豁免第三条注销——见下两行与定稿节轴丁)**) | `begin_battle(encounter)`;窗口/刷新意图提交面(扮演 D1);`level_clear()`;步骤流(输出契约) | B2/B3/B4 全调用面(**唯一调用方=B1 域文件集:battle_orchestrator.gd + settlement/ 五段段类 + damage_controller + 拆件后三新件**);A3 request_refresh 代理 + 回发;A2 install/retire + 三事件订阅;A1 generate(attempt 非 scope 事件);D2 SettlementTable + set_reload_gate | 无(零随机、禁 await——切片 88 冒烟实证可回放) | -| **BattleFxHost**(`core/battle_fx_host.gd`,B1 域·效果引擎宿主件,2026-10-26 编排域拆件设计定稿——已建件(迭代 40 实装)) | 效果引擎挂点施加面唯一承载(自 battle_orchestrator 收编 fx 族):事件发射与事实判定(_fx_emit/_fx_fact)、主角 AC 基线与本轮/本战 AC 累积、bonus_delta 四轴累积(战末宿主 drain 汇入账本)、揭示待兑队列与兑付(含 _fx_revealing 再入闸——同步信号回环防二次缓冲二次兑付)、树规则合成订阅的 round/battle 桶计数器持有(桶随编排器生灭语义不变);2026-11-02 轴戊设计闭合落地(迭代 49 卡①):效果端口件为业务类朝向机房的窄门面——端口在本件组建、bind_port 组装期转注两业务类,计数器账面收归本件;实测类变量 15 | 构造=引用束注入(防 _init max-parameters 新键);bind 时注入 emit Callable(行发射经宿主协议面单点)与兑付 Callable(RewardGrant 授予面——揭示队列 flush 回调);只读投影分两类消费方:AC 累积/bonus_delta 供宿主呈现快照与战末 drain,揭示态供宿主 A2 订阅旁路判定;`luck_bias_for(cell_count) -> int` 偏运合计查询口(体内三参形 dispatch——reward_roll 发射与 bias_rewards 求和自 RewardEconomy 收回本件,RewardEconomy 经注入 Callable 消费) | EffectEngine(EffectContext 引用束);RngServiceCore(fx_reveal 封闭流——除该流外零随机);A2 minesweeper(板读与 fx_reveal 调用);A3 action_economy(queue_ap_delta/charge_layers 读);B3 status_container 读;B2 unit_container 读(hp_ratio);DamageController(set_hero_ac_override);ConfigDB;encounter 引用 | 无(零 await——效果引擎全同步解释器) | -| **RewardGrant**(`core/reward_grant.gd`,B1 域·奖励授予件,2026-10-26 编排域拆件设计定稿——实现批建件) | 奖励授予唯一兑付管线(自 battle_orchestrator 收编 grant 族):极性字典路由与封印溢价兑付(_grant_routed)、三种行应用(flat/percent/gp)、伤害单据提交面(_submit 族)、清图奖励与身份授予、秘宝使用编排(use_treasure 四步)、战斗域 GP 缓冲 escrow 与授予段暂存伤害闸(_defer_board_damage/_deferred_board) | use_treasure 编排入口(treasure_interact_controller 经组合根现值回调直连);授予入口(结算段类直调);只读投影(escrow 读与 GP 掉落合计——宿主呈现快照与 _roll_gp_drop 消费) | B4 RewardEconomy(polarity_row/grant);B1 域 DamageController(开单);BattleFxHost 引用(treasure_used 事件发射与计数器消耗);A2 minesweeper(校验回调/fx_reveal/remove_mines_in);A3 action_economy(相位闸/grant_ap/queue_ap_delta);B3 status_container(apply_effect/池读);B2 unit_container(hero_unit/heal);ConfigDB;注入 emit Callable、宿主 fatal Callable(battle_result 状态机唯一写点留宿主)、宿主 attune 读投影(_attune_safe_seen)、encounter 账本引用;TreasureItems 经宿主 setter 转发注入(库存注入时序在宿主构造之后) | 无(零随机零 await——授予期零随机口径,roll 值授予前已定) | -| **damage_controller**(B1 域·伤害单据管线) | 伤害单据唯一兑现管线(单据九栏目声明→分量掷点/克制修正/伤害下限归一→明细行发射;双方同规);`damage_taken` 唯一发射口(_emit_hero_damage_taken)+唯一消费族(_apply_hero_damage_effects)——敌方攻击/地形/危险格/错误封印直伤四路径统一发射,board_flat_hero 结账前统一发射 | 兑付入口(编排侧开单)+ fx 揭示回调注入位;实测类变量 12 | B2 单位实例(单据目标传入);B1 注入(EffectPort 端口引用——轴戊设计闭合改经端口发射,迭代 49 卡① 建件;EffectContext 引用束与编排回调收归宿主侧 BattleFxHost 域,业务类零引擎直连) | 无 | -| **BattleRefreshFlow**(`core/battle_refresh_flow.gd`,B1 域·换图刷新流程件,已建件——迭代 46) | 弃图刷新流程唯一承载(自编排器收编):刷新可用性门(相位/每轮上限/储备门槛)、折后价单点(_effective_refresh_cost——专长行声明序第一命中、floor 取整、can 与执行同源)、换图执行序(扣储备→used+1→旧资源退役→旧板退役→装新板→board_refreshed 成功事实登记) | can_refresh/execute 两公开入口;调用路径呈现层→编排器两公开方法单行转发→本件;A3 request_refresh 收折后价入参 | 编排器(宿主,B1 域内唯一调用方约束同族适用);A3 action_economy(折价扣费与拒绝判据);A2 装板壳(装板与退役);RewardGrant(apply_board_refreshed 成功事实消费);feats 折价行经 ConfigDB;static_scan S7_B1_SET 已增补本件(判据口径不变) | 无(零随机零 await) | +| **BattleFxHost**(`core/battle_fx_host.gd`,B1 域·效果引擎宿主件,2026-10-26 编排域拆件设计定稿——已建件(迭代 40 实装)) | 效果引擎挂点施加面唯一承载(自 battle_orchestrator 收编 fx 族):事件发射与事实判定(_fx_emit/_fx_fact)、主角 AC 基线与本轮/本战 AC 累积、bonus_delta 四轴累积(战末宿主 drain 汇入账本)、揭示待兑队列与兑付(含 _fx_revealing 再入闸——同步信号回环防二次缓冲二次兑付)、树规则合成订阅的 round/battle 桶计数器持有(桶随编排器生灭语义不变);2026-11-02 轴戊设计闭合落地(迭代 49 卡①):效果端口件为业务类朝向机房的窄门面——端口在本件组建、bind_port 组装期转注两业务类,计数器账面收归本件;实测类变量 15 | 构造=引用束注入(防 _init max-parameters 新键);bind 时注入 emit Callable(行发射经宿主协议面单点)与兑付 Callable(RewardGrant 授予面——揭示队列 flush 回调);+mark_new_resource_type/+add_bonus_delta 两公开累积方法(grant 消费面——类变量 15 不变,方法-only);只读投影分两类消费方:AC 累积/bonus_delta 供宿主呈现快照与战末 drain,揭示态供宿主 A2 订阅旁路判定;`luck_bias_for(cell_count) -> int` 偏运合计查询口(体内三参形 dispatch——reward_roll 发射与 bias_rewards 求和自 RewardEconomy 收回本件,RewardEconomy 经注入 Callable 消费) | EffectEngine(EffectContext 引用束);RngServiceCore(fx_reveal 封闭流——除该流外零随机);A2 minesweeper(板读与 fx_reveal 调用);A3 action_economy(queue_ap_delta 读);B3 status_container 读;B2 unit_container 读(hp_ratio);DamageController(set_hero_ac_override);ConfigDB;encounter 引用 | 无(零 await——效果引擎全同步解释器) | +| **RewardGrant**(`core/reward_grant.gd`,B1 域·奖励授予件,2026-10-26 编排域拆件设计定稿——实现批建件) | 奖励授予唯一兑付管线(自 battle_orchestrator 收编 grant 族):极性字典路由与封印溢价兑付(_grant_routed)、三种行应用(flat/percent/gp)、伤害单据提交面(_submit 族)、清图奖励与身份授予、秘宝使用编排(use_treasure 四步)、战斗域 GP 缓冲 escrow 与授予段暂存伤害闸(_defer_board_damage/_deferred_board) | use_treasure 编排入口(treasure_interact_controller 经组合根现值回调直连);授予入口(结算段类直调);+feat_yield_adjust(专长收益调整——自编排器归位);只读投影(escrow 读与 GP 掉落合计——宿主呈现快照与 _roll_gp_drop 消费) | B4 RewardEconomy(polarity_row/grant);B1 域 DamageController(开单);BattleFxHost 引用(treasure_used 事件发射与计数器消耗);A2 minesweeper(校验回调/fx_reveal/remove_mines_in);A3 action_economy(相位闸/grant_ap/queue_ap_delta);B3 status_container(apply_effect/池读);B2 unit_container(hero_unit/heal);ConfigDB;注入 emit Callable、宿主 fatal Callable(battle_result 状态机唯一写点留宿主)、宿主 attune 读投影(_attune_safe_seen)、encounter 账本引用;TreasureItems 经宿主 setter 转发注入(库存注入时序在宿主构造之后) | 无(零随机零 await——授予期零随机口径,roll 值授予前已定) | +| **damage_controller**(B1 域·伤害单据管线) | 伤害单据唯一兑现管线(单据九栏目声明→分量掷点/克制修正/伤害下限归一→明细行发射;双方同规);`damage_taken` 唯一发射口(_emit_hero_damage_taken)+唯一消费族(_apply_hero_damage_effects)——敌方攻击/地形/危险格/错误封印直伤四路径统一发射,board_flat_hero 结账前统一发射 | 兑付入口(编排侧开单)+ fx 揭示回调注入位;+hero_atk()/static hits_of()/emit_hero_damage_taken 公开化(_emit 去下划线非并存——编排器与段类消费);实测类变量 12→13(+facts 构造注入) | B2 单位实例(单据目标传入);B1 注入(EffectPort 端口引用——轴戊设计闭合改经端口发射,迭代 49 卡① 建件;EffectContext 引用束与编排回调收归宿主侧 BattleFxHost 域,业务类零引擎直连) | 无 | +| **BattleRefreshFlow**(`core/battle_refresh_flow.gd`,B1 域·换图刷新流程件,已建件——迭代 46) | 弃图刷新流程唯一承载(自编排器收编):刷新可用性门(相位/每轮上限/储备门槛)、折后价单点(_effective_refresh_cost——专长行声明序第一命中、floor 取整、can 与执行同源)、换图执行序(扣储备→used+1→旧资源退役→旧板退役→装新板→board_refreshed 成功事实登记) | can_refresh/execute 两公开入口(构造=实例束注入 8 键——facts/db/action_economy/fx_host/reward_economy/minesweeper/install_cb/grant_seg;类变量 0→8);调用路径呈现层→编排器两公开方法单行转发→RoundCycle.refresh_flow() 取件→本件;grant_seg 段间引用直接交接(编排器 _rounds._grant_seg 跨两层链式取段消灭);A3 request_refresh 收折后价入参 | 编排器(宿主,B1 域内唯一调用方约束同族适用);A3 action_economy(折价扣费与拒绝判据);A2 装板壳(装板与退役);RewardGrant(apply_board_refreshed 成功事实消费);feats 折价行经 ConfigDB;static_scan S7_B1_SET 已增补本件(判据口径不变) | 无(零随机零 await) | | **BoardInstaller**(`core/board_installer.gd`,B1 域·装板域件,2026-10-29 尾波清偿批设计闭合——实现批建件,细则见「战斗编排域拆件定稿」节轴丙) | 棋盘安装与变异布置域唯一承载(自 battle_orchestrator 收编装板族六函数):生成受理、全局作用域变异决议、资源摇号资格域组装(roll_board 恰一次)、region 变异决议与连通片布置;BoardGenerator 实例随件自建自接线(宿主成员退役)——宿主侧装板后状态复位(封印/完美计数清零、板序推进、board_changed 发射、秘宝叠加层退役)留宿主薄壳,时序逐字保持 | `install(during_round) -> bool` 单入口;构造=引用束注入(rng/db/minesweeper/reward_economy/encounter 只读引用+宿主 fatal Callable——防 _init max-parameters 新键) | A1 board_generator(件内持有);A2 install_board;B4 roll_board/board_skew 写;A4 变异决议行集经 ConfigDB;board_gen/variant_place 两封闭流随件、流名与开流时点零漂移 | 无(零 await——装板全同步) | -| **RoundCycle**(`core/round_cycle.gd`,B1 域·轮循环驱动件,已建件——迭代 44) | 轮循环驱动域唯一承载(自宿主收编 7 成员):结算五段段件持有与驱动、重入门闸、开轮摇号、踩雷账 | 三参直构(host/fx_host_ref/reward_grant_ref——五段构造透传不落成员);段驱动入口由宿主接线调用;实测类变量 8/公开方法 3 | B1 宿主;settlement/ 五段段类;A3 相位读 | 无 | +| **RoundCycle**(`core/round_cycle.gd`,B1 域·轮循环驱动件,已建件——迭代 44) | 轮循环驱动域唯一承载(自宿主收编 7 成员):结算五段段件持有与驱动、重入门闸、开轮摇号、踩雷账 | 引用束注入(编排器 20 键封闭束,解包自用七键后原束分发五段;持有 BattleRefreshFlow);段驱动入口由宿主接线调用;公开方法 3→4(refresh_flow() 读出口);实测类变量 8→15(贴顶禁再增) | B1 宿主;settlement/ 五段段类;A3 相位读 | 无 | | **BattleFacts**(`core/battle_facts.gd`,B1 域·战斗事实件,已建件——迭代 44) | 战斗事实域唯一承载(自宿主收编 14 成员):受理事实(encounter)、轮 facts 缓冲(reveals/seals/path)、封印判定账、事实溯源、同调快照读面;attune 状态两成员随件(行为函数留宿主) | 零参直构;宿主与段类经注入引用读写;实测类变量 15(贴顶)/公开方法 4(reset_round+三 mark 写口) | B1 宿主;A2/A3 只读 | 无 | -| **settlement/ 五段段类**(B1 域·结算段件) | B1 每轮结算序列的五段逻辑件(授予/增益减益/战斗/衰减/判定——细则见下「战斗域装配现状」节) | 段处理入口(B1 接线调用);可直接 `new()` 单测 | B2/B3/B4 兑付面与 B1 轮 facts 缓冲(各段按职责) | 无 | +| **settlement/ 五段段类**(B1 域·结算段件) | B1 每轮结算序列的五段逻辑件(授予/增益减益/战斗/衰减/判定——细则见下「战斗域装配现状」节) | 段处理入口(B1 接线调用);构造=引用束注入(各段断言各自必需键);段类对编排器零引用(注入 Callable 亦属接线面);可直接 `new()` 单测 | B2/B3/B4 兑付面与 B1 轮 facts 缓冲(各段按职责) | 无 | | **level_runner**(C1-lite,切片已建) | 关卡域生命周期(节点链推进、共享 B4 + HP 携带、关卡末 level_clear) | 节点推进接口;LevelTable(`level.tres`——节点 enum {battle,reward,rest,boss}、末节点必须 Boss、ConfigDB 跨表校验⑧) | B1(直构 BattleOrchestrator 接线战斗)、ConfigDB LevelTable | 无 | | **run_structure**(C2) | 冒险/关卡序列、失败重开、**master_seed 唯一接线方** | (契约规范源:`../../gdd/systems/冒险循环/冒险结构.md`) | RngService.set_master_seed、C3/D2 | 无 | | **difficulty**(C3) | DifficultyTable 回填、全部曲线数值调参所有权、战斗期望表(切片 monte_carlo 为工具原型) | 调参输出(经 D2 R1 解析/编排器传递,禁反向调用生成) | ConfigDB、B1 对账输出(调参约束清单)、A1 报告 C | 无 | @@ -143,10 +143,10 @@ - **轴甲两件**:battle_orchestrator(拆件时 S13 全库单文件最大户——行数与成员数为历史读数,冻结计数不登记,查 git)按变化原因拆出 BattleFxHost(效果引擎宿主域)与 RewardGrant(奖励授予域)两协作件;宿主保留架构在册职责全部——战斗状态机与生命周期、轮 facts 缓冲(_facts_reveals/seals/path)、A2 三事件订阅、结算五段驱动、attune 族原位、行发射基建(_emit_row/_assert_row_source/_fatal)、呈现投影(presentation/diagnostic_snapshot 唯一出口不变)、刷新面、nest_preview_count(巢穴预告读数口——外部直读面 main.gd 与 treasure_effects_test 随批点名冻结)。拆件动机与残留债口径见待办清单「gdstyle 存量债全量清偿」条目。 - **轴丙一件(2026-10-29 尾波清偿批设计闭合——实现批建件)**:battle_orchestrator 装板域六函数(`_install_new_board`/`_resolve_global_variant`/`_place_variants`/`_place_variants_apply`/`_variants_fringe`/`_adjacent_to_packs`,约 140 行;全仓仅宿主三调用点——begin_battle/中途刷新受理/player_request_refresh,实查零外部调用)按变化原因拆出 BoardInstaller,职责语句「棋盘安装与变异布置域」(生成→全局变异决议→装板受理→资源摇号→变异布置;单一变化原因=棋盘设置顺序与变异布置算法)。形态两修正(实测裁,与初案「逐字搬运」之差):①宿主复位块不随件——`_install_new_board` 体内五处计数清零、板序推进、board_changed 发射与秘宝叠加层退役留宿主薄壳 `_install_and_reset`,三调用点改调薄壳、时序逐字;②`_board_generator` 全文件仅装板族使用——实例随件自建自接线(fatal 经注入 Callable),宿主成员退役(类变量 38→37,禁无效成员义务)。encounter(23 处跨宿主)与 _reward_economy(18 处)确认留宿主、经引用束注入。文件长键(1035/1000)随本件迁出归绿;attune 族与 begin_battle 受理段序禁动不变。 - **轴丁两件(2026-10-29 零豁免裁设计闭合——实现批建件)**:RoundCycle(轮循环驱动件)与 BattleFacts(战斗事实件)见功能层表两行——宿主 38(轴丙落地后 37)→15,S13 豁免第三条注销;宿主保留面改登记为「战斗状态机与生命周期、行发射基建(_emit_row/_assert_row_source/_fatal)、呈现投影(两快照出口签名不变)、刷新面、nest_preview_count」;attune 族处置由下一条改判;treasure_inventory 注入改址追认——原「外部赋值路径零改址」句失效,level_runner 经 RewardGrant 出口直注;成员级对账以需求卡片为卡内契约(开工 T0 复核)。 -- **轴戊两件(2026-11-02 用户裁甲案设计闭合——已建件,迭代 49 卡① 合回,git 提交 848723b5)**:①**效果端口件 EffectPort**(`core/effect_port.gd`)——职责语句「战斗业务类唯一的效果发射出口:收事件与载荷、交效果引擎结算、取回命中批」;实测形态=六 Callable 路由、bind_port 组装期转注、闭面五键 biz_fact、未绑零扰动缺省;`DamageController`/`ActionEconomy` 各持端口引用(同一实例、构造注入),`EffectEngine`/`EffectContext` 引用与计数器账面(value_counter 层值读后清零)收归宿主侧(BattleFxHost 域),业务类零引擎直连、零账面触碰;facts 取值束(dig_streak/charge_layers/rider_tier_*)与入站回调束(reveal/ac)随发射契约归宿主侧注入面;端口**单实现零接口抽象**(无基类无多态——GDScript 无 interface,本案不需要);端口与宿主经注入 Callable 束协作、零宿主对象引用(跨件单向接线条款适用,禁双向强引用)。②**掷格件 RewardRoller**(`core/reward_roller.gd`)——职责语句「装配期格面资源摇号:池行装配、区间行 roll、权重合成(偏运硬币/board_skew 两路投影)」;实测形态=roll 批束四键(mapping/power_roll/clear_identity/clear_power)、选行算子 `_weighted_pick_row` 返表行、fatal 经构造 Callable 链;受理账面(grant/身份查询/快照/retire/polarity_row)留 `RewardEconomy`,衔接面=格→奖励身份映射(掷格件产出、受理件接收);掷格件经注入 RngServiceCore 取号(roll_board 流 scope=每次 install 批不变、取号序零漂移)。行为零变化红线沿本节「验收红线」全款:命中序=声明序、明细行协议词表零触碰、`_ineffective_row` 载荷 deferred 自描述键观测面不回退(2026-11-02 迭代 48 卡① 甲案在案)、EV/MC 锚同种子逐位零漂移——round_flow 逐位回放 134 检查为主证(红线成立);两新件 S13 预算随卡「实现规范预算」三查已过(新件全默认阈值内、gdstyle 基线外新违规 0),`RewardEconomy` 类变量随掷格面迁出 15→11;S7 B1 域文件集与 S8 await 文件集已随批增行。 +- **轴戊两件(2026-11-02 用户裁甲案设计闭合——已建件,迭代 49 卡① 合回,git 提交 848723b5)**:①**效果端口件 EffectPort**(`core/effect_port.gd`)——职责语句「战斗业务类唯一的效果发射出口:收事件与载荷、交效果引擎结算、取回命中批」;实测形态=六 Callable 路由、bind_port 组装期转注、闭面四键 biz_fact(dig_streak/hp_ratio/rider_tier_bonus/rider_tier_crit——charge_layers 键退役后宿主应答 null)、未绑零扰动缺省;`DamageController`/`ActionEconomy` 各持端口引用(同一实例、构造注入),`EffectEngine`/`EffectContext` 引用与计数器账面(value_counter 层值读后清零)收归宿主侧(BattleFxHost 域),业务类零引擎直连、零账面触碰;facts 取值束(dig_streak/rider_tier_*)与入站回调束(reveal/ac)随发射契约归宿主侧注入面;端口**单实现零接口抽象**(无基类无多态——GDScript 无 interface,本案不需要);端口与宿主经注入 Callable 束协作、零宿主对象引用(跨件单向接线条款适用,禁双向强引用)。②**掷格件 RewardRoller**(`core/reward_roller.gd`)——职责语句「装配期格面资源摇号:池行装配、区间行 roll、权重合成(偏运硬币/board_skew 两路投影)」;实测形态=roll 批束四键(mapping/power_roll/clear_identity/clear_power)、选行算子 `_weighted_pick_row` 返表行、fatal 经构造 Callable 链;受理账面(grant/身份查询/快照/retire/polarity_row)留 `RewardEconomy`,衔接面=格→奖励身份映射(掷格件产出、受理件接收);掷格件经注入 RngServiceCore 取号(roll_board 流 scope=每次 install 批不变、取号序零漂移)。行为零变化红线沿本节「验收红线」全款:命中序=声明序、明细行协议词表零触碰、`_ineffective_row` 载荷 deferred 自描述键观测面不回退(2026-11-02 迭代 48 卡① 甲案在案)、EV/MC 锚同种子逐位零漂移——round_flow 逐位回放 134 检查为主证(红线成立);两新件 S13 预算随卡「实现规范预算」三查已过(新件全默认阈值内、gdstyle 基线外新违规 0),`RewardEconomy` 类变量随掷格面迁出 15→11;S7 B1 域文件集与 S8 await 文件集已随批增行。 - **跨件单向接线**:RewardGrant 持 BattleFxHost 引用(treasure_used 事件发射与计数器消耗);BattleFxHost 对授予面走 bind 时注入的兑付 Callable(揭示队列 flush 回调)——禁双向强引用(两件均 RefCounted,环引用随每战新建泄漏)。行发射经 bind 时注入的 emit Callable(协议面单点留宿主——CurioDeck bind_handlers 同款先例,禁件回调宿主私有族);轮 facts 缓冲留宿主、fx 件经注入取值;_seal_consumed 留宿主(与 A2 seal_judged 订阅同域);fatal 经注入 Callable 转宿主 _fatal(battle_result 状态机唯一写点不变)。注入 Callable 亦属接线面、同单向纪律——禁为省参数改持对象引用。授予件对账本零强引用:战斗期消费经 `battle_hooks` 三键回调束(attune_consume/vision_add/negative_blast,bind_battle 缺键 assert),宿主侧三单点记账(2026-10-28 迭代 40 合并适配实装——RunLedger 类已随迭代 39 退役,直持对象引用无处可指)。 - **战斗域读面(RunLedger 退役后)**:账本读经编排器 `_journal()`/`_attune_loadout()` 现值派生(GainJournal/AttuneLoadout,enc 派生、无成员接收);冒险桶经 `enc["adv_bucket"]` 下传 `battle_fx_host.mount_buckets`;战末 bonus 四轴经 `GainJournal.gain_bonus` 汇入(2026-10-27 迭代 39 主角账三件落地、迭代 40 合并适配承接)。 -- **settlement/ 段类随动**:段类构造注入直持宿主+两新件三引用(Middle Man 禁令封转发壳——调用点改指),授予段读写面点名:_grant_routed×5/_submit×6/escrow 写/_fx_new_resource_types/_feat_first_dig_used/_fx_bonus_delta 写/_apply_ac_bonus/_fx_enqueue_reveal/_flush_pending_reveals/_grant_clear_reward/counters_ctx;战斗段 _defer_board_damage 复位与 _deferred_board 结账改指 RewardGrant。四个授予段 helper(_feat_yield_adjust/_harmful_variants/_harmful_adjacent/_hits_of)与 _pool_effective/perfect_sweep_earned 留宿主(段类经宿主引用直调,现状形态)。 +- **settlement/ 段类随动(2026-11-04 迭代51卡② 换代)**:段类构造=引用束注入(编排器 20 键封闭束分发——各段断言各自必需键),段类对编排器零引用(跨件单向接线,注入 Callable 亦属接线面)。四个授予段 helper 归位:_feat_yield_adjust→RewardGrant(feat_yield_adjust)、_harmful_variants/_harmful_adjacent→minesweeper_rules(harmful_variants/harmful_adjacent)、_hits_of→damage_controller(static hits_of);_pool_effective/perfect_sweep_earned 留宿主(段类经编排器公开读投影消费)。 - **attune 族处置(2026-10-29 零豁免裁改判,原「原位保留」失效)**:attune 状态两成员归 BattleFacts、行为函数留宿主——迭代 39 副卡(AttuneLoadout 充能单源化)语义领地不破,外部三面消费点零改址;RewardGrant 经宿主 attune 读投影取 _attune_safe_seen 形态不变。 - **呈现零变化**:两快照出口签名与载荷逐字不变,内部改读两件只读投影(快照本体不读揭示态——揭示态投影消费方=宿主 A2 订阅旁路判定);treasure_interact_controller 三触点分家——use_treasure 经组合根现值回调改注 RewardGrant(每战新建编排器,禁一次性直引防悬挂),minesweeper 读与 attune_convert_state 仍走宿主取值回调(双取值面);nest_preview_count 直读面零变化。 - **S13 键账收敛义务**:12 个超标键随函数迁入新文件=基线外 NEW(use_treasure 长度/分支/局部/返回×4、_grant_routed 参数 8、_dispatch_row 参数 6、_apply_percent_row 参数 6、_apply_gp_row 参数 6、_apply_flat_row 参数 7+返回 9、_submit_flat_hero 参数 7、_fx_fact 返回 7)——卡内同步收敛为本波义务(_grant_routed 等签名随引用束注入改形、use_treasure 体拆分),禁波 0 合并 refresh 吸收新文件未还键;新件 _init 引用束注入防 max-parameters 新键。 diff --git a/design/engineering/process-conventions.md b/design/engineering/process-conventions.md index b4eeec4b..3ed32191 100644 --- a/design/engineering/process-conventions.md +++ b/design/engineering/process-conventions.md @@ -11,7 +11,7 @@ 1. **worktree 车道(一切面)**:每回合先建独立 worktree(建区粒度=回合,会话单区细则见第 5 条):`git worktree add ../g-plan2-<任务名> -b <任务分支>`;建区后立刻跑 `tools/setup_worktree_userdir.sh`——给该区独立 Godot user 目录(测试夹具、试玩日志、截图产物不与其他区共用;主区不生成,真实档保持原位)。所有改动与提交都在 worktree 内自由进行——commit 点零钩子检查(`tools/hooks/pre-commit` 已删除)。豁免面仅 `.zcode/`(钩子与配置)与 `.qoder/`(本机 harness 配置)允许主工作区直改——两份实测均不入 git(走 worktree 反而带不进去,改动只对本机生效) 2. **收口顺序(固定)**:**冻结 → 件核 → 并 master → 重塑 → 主区合回 → 删区**——代码与断言改完即冻结,全仓件核 grep 查残留;master 已被别的批次推进时先在 worktree 内 `git merge master` 解冲突(必须在合回之前,合回后才并=CI 验的是中间态);**重塑**=迭代分支(iter 形)合回前执行 `python tools/reshape_cards.py`,把分支线性史按卡末态快照压成一卡一笔(可选追加一笔纯文档收尾),master 台账由此每卡一行——工具自带「重塑前后树逐字节一致」断言与 backup 分支,不改任何文件内容;非迭代批免重塑;然后主工作区 `git merge --no-ff <任务分支>`——这是主区唯一合法写动作(合回守卫对迭代分支数卡校验,未归卡提交拦下)。**合回落地即 `git worktree remove`+删分支(合回即删,2026-09-19 原裁);post-merge 钩子已在合回落地时自动触发 CI,红态不回滚合并——新开修复 worktree(`fix-<任务名>` 分支,非 iter 形免重塑免数卡)修复提交再合,落地复验追绿后删修复区**。游戏类测试(冒烟/单测/MC/探针)批内默认零执行(两入口铁规,见 §4),用户点名或当场问才跑 -3. **合回后验证(远端 CI,2026-11-03 用户裁取代本地 CI)**:git merge 合回 master 落地后 post-merge 钩子(`tools/hooks/post-merge`)自动 `git push origin master` 触发远端 CI(Gitea Actions,runner=Mac 本机 host 模式),工作流按改动域分流(分流算法单点=`tools/ci/domain_route.sh`:游戏码批=两域全量含渲染闸,文档批=文档域秒级闸,纯闸件/管线批=零触发)——唯一强制验证点。远端结果用 `tools/ci_check.sh <合并提交>` 按需现查(读该提交任务的 run 自身 `status`/`conclusion`,只呈报、不落盘),agent 开工先读 CI 状态的纪律不变,红未修不开新批。CI 红态不回滚合并——修复走新开修复 worktree(`fix-<任务名>` 分支,非 iter 形免重塑免数卡),修复合回落地即再推再验追绿(追绿同链;本地跑批件 `ci_runner.sh` 与本地追绿钩子 post-commit 已退役)。导入缓存刷新(.godot 不入 git 的在册坑)由工作流「导入缓存刷新」步接管。**合回零等待纪律(2026-11-04 用户裁,取代 2026-11-02 回执等待纪律)**:合回落地即向用户呈报本批总结并止回合——不挂后台轮询、不等回执、不被唤醒;CI 结论什么时候要看就现查一次(`tools/ci_check.sh`,run 那时早已落定,秒级)。退役缘由=原轮询件把「commit status 离开 pending」当终局判据,会把 run 未落定期的尝试级失败写成终局红(run 37 实证:开跑 36 秒写红,该 run 三分半后 `conclusion=success`),且零触发批与 runner 排队必熬满超时再写红;同 commit 的多路轮询还重复覆写同一份判定。跑闸等一切分钟级跑批的等待纪律不变——后台运行,禁前台 sleep/轮询循环。 +3. **合回后验证(远端 CI,2026-11-03 用户裁取代本地 CI)**:git merge 合回 master 落地后 post-merge 钩子(`tools/hooks/post-merge`)自动 `git push origin master` 触发远端 CI(Gitea Actions,runner=Mac 本机 host 模式),工作流按改动域分流(分流算法单点=`tools/ci/domain_route.sh`:游戏码批=两域全量含渲染闸,文档批=文档域秒级闸,纯闸件/管线批=零触发)——唯一强制验证点。远端结果用 `tools/ci_check.sh <合并提交>` 按需现查(读该提交任务的 run 自身 `status`/`conclusion`,只呈报、不落盘),agent 开工先读 CI 状态的纪律不变,红未修不开新批。**绿须坐实**:零触发批的 run 照样建、照样 conclusion=success,但跑闸步是 `skipped`(run 55 实证)——一条闸都没跑不构成验证,现查件对此呈报「未验」(退出码 4),禁当绿证用;job 列表为空、取不到步级读数或工作流里没有跑闸步时呈报「不可判」,同样禁当绿证。CI 红态不回滚合并——修复走新开修复 worktree(`fix-<任务名>` 分支,非 iter 形免重塑免数卡),修复合回落地即再推再验追绿(追绿同链;本地跑批件 `ci_runner.sh` 与本地追绿钩子 post-commit 已退役)。导入缓存刷新(.godot 不入 git 的在册坑)由工作流「导入缓存刷新」步接管。**合回零等待纪律(2026-11-04 用户裁,取代 2026-11-02 回执等待纪律)**:合回落地即向用户呈报本批总结并止回合——不挂后台轮询、不等回执、不被唤醒;CI 结论什么时候要看就现查一次(`tools/ci_check.sh`,run 那时早已落定,秒级)。退役缘由=原轮询件把「commit status 离开 pending」当终局判据,会把 run 未落定期的尝试级失败写成终局红(run 37 实证:开跑 36 秒写红,该 run 三分半后 `conclusion=success`),且零触发批与 runner 排队必熬满超时再写红;同 commit 的多路轮询还重复覆写同一份判定。跑闸等一切分钟级跑批的等待纪律不变——后台运行,禁前台 sleep/轮询循环。 4. **执法分层(全机械,零自觉依赖)**:①`.zcode/hooks/worktree-guard.sh`(PreToolUse,本机件不入 git)——agent 侧:主工作区 Edit/Write 与主区非 merge `git commit` 拦截(豁免 `.zcode/`、`.qoder/`;worktree 内目标快速放行;合并收尾提交凭 MERGE_HEAD 豁免)、`git commit --no-verify` 拦截(该旗标仅属用户)、iter 分支合回的一卡一提交数卡校验、规则闸(写 design//game/ 前核对会话规约读取记录)。②post-merge 钩子——远端 CI 触发(只推送,不挂等待;仅主工作区,任务 worktree 内的合并不触发)。③git 层不设车道钩子(pre-commit 直改闸已退役)——用户手工改动不受限;ZCode 层只约束 agent(子代理不经守卫层) 5. **会话单区(2026-11-04 用户裁)**:建区粒度=回合——同一时刻每会话至多一个 worktree 在役;合入删区之前,会话内用户追加的事项一律并入在役区推进,禁为追加事项另开新区。区内全部事项完成后只做一次合入(一次 `git merge --no-ff`、post-merge 一次推送、远端 CI 只跑一次),追加事项在合入提交信息里分列;无改动需求的事项不建区。合回删区后用户再发令的事项=新回合,另开新区(区名取该回合主任务名)。CI 红的 `fix-<任务名>` 修复区属同一回合的追绿延续,不另算新区。迭代实现批(iter 形分支)独占回合——其他类事项不得并入迭代区(合回守卫数卡校验本就拦未归卡提交),待其合回后按新回合另开。 diff --git a/design/engineering/test-conventions.md b/design/engineering/test-conventions.md index a8fa1e4e..ffc6c41a 100644 --- a/design/engineering/test-conventions.md +++ b/design/engineering/test-conventions.md @@ -128,7 +128,7 @@ 3. 检查测试削弱:删除断言、放宽阈值、缩小扫描面、换下层直调,逐处要卡片申报或用户批准。 4. 核对内部字段直查的受控例外:直查行是否已在对照表注明理由(该行为无公开可观测面可钉)。 -**审计深度分级(2026-11-04 立)**:审计按卡内申报的验收档(§8.3)逐卡定深度;梯度只落在昂贵的判断件上,机械且堵造假向量的两件(削弱检查、例外核对)三档全保留不抽。中/低档省略的测试复跑以远端 CI 读数为执行证据——`tools/ci_check.sh <合并提交>` 的现查输出(commit+run 号+conclusion)是机器产物,run 号在远端永久可复核,审计报告照抄该行即可(2026-11-04 用户裁:回执等待件退役,证据由落盘文件改为现查读数;「不采信实现者自述已全绿」的口径不变): +**审计深度分级(2026-11-04 立)**:审计按卡内申报的验收档(§8.3)逐卡定深度;梯度只落在昂贵的判断件上,机械且堵造假向量的两件(削弱检查、例外核对)三档全保留不抽。中/低档省略的测试复跑以远端 CI 读数为执行证据——`tools/ci_check.sh <合并提交>` 的现查输出(commit+run 号+conclusion)是机器产物,run 号在远端永久可复核,审计报告照抄该行即可;照抄前先核对读数必须是「绿」——「未验」(零触发批跑闸步全跳过)与「不可判」不作证据,那种批的回补办法是等一次含代码面的合回或用户自发全量回归(2026-11-04 用户裁:回执等待件退役,证据由落盘文件改为现查读数;「不采信实现者自述已全绿」的口径不变): | 审计动作 | 高 | 中 | 低 | |---|---|---|---| diff --git a/game/core/breakpoint_store.gd b/game/core/breakpoint_store.gd index 699a5367..85af6d25 100644 --- a/game/core/breakpoint_store.gd +++ b/game/core/breakpoint_store.gd @@ -222,7 +222,7 @@ func _bp_read_int(key: String, bp: Dictionary, fallback: int, params: Dictionary # ---- 断点域六成员公开读写面(5.1 封装修复——宿主私取清零:方法体一律一行转发自有成员,零逻辑增量)---- # 断点承载注入(宿主构造后接线——save_manager 后绑) -func bind_save_manager(sm) -> void: +func bind_save_manager(sm: SaveManagerCore) -> void: _save_manager = sm diff --git a/game/tests/unit/contracts/system_contracts_test.gd b/game/tests/unit/contracts/system_contracts_test.gd index 4c212e80..350e1308 100644 --- a/game/tests/unit/contracts/system_contracts_test.gd +++ b/game/tests/unit/contracts/system_contracts_test.gd @@ -13,6 +13,7 @@ const RngServiceScript := preload("res://core/rng_service.gd") const StatusContainerScript := preload("res://core/status_container.gd") const UnitContainerScript := preload("res://core/unit_container.gd") const DamageControllerScript := preload("res://core/damage_controller.gd") +const BattleFactsScript := preload("res://core/battle_facts.gd") const Kit := preload("res://tests/unit/test_kit.gd") # T6 收口:_check/汇总退出样板单点 @@ -98,13 +99,13 @@ func _test_ticket_nine_columns() -> void: func _bare_controller(): var db = ConfigDBScript.new() - # 只取 open_ticket 纯构造面——四个依赖一律传真实实例,不用空桩: - # DamageController 的 db/rng/units/effects 全是定型标注,传无类型的空桩会触发 + # 只取 open_ticket 纯构造面——五个依赖一律传真实实例,不用空桩: + # DamageController 的 db/rng/units/effects/facts 全是定型标注,传无类型的空桩会触发 # 「Trying to assign value of type '' to a variable of type '…'」脚本错误——该错误不改退出码, # 却让赋值静默失败(成员留 null),脚本错误扫描落地后必红。三者均可零消费构造。 var units = UnitContainerScript.new(db) var effects = StatusContainerScript.new(db) - return DamageControllerScript.new(db, RngServiceScript.new(), units, effects) + return DamageControllerScript.new(db, RngServiceScript.new(), units, effects, BattleFactsScript.new()) # ---- B4→B3:增益授予布尔受理口径(受理/拒绝二元面 + 投影一致性) ---- diff --git a/game/tests/unit/core/save_manager_domain_test.gd b/game/tests/unit/core/save_manager_domain_test.gd index 26211e86..4574f1c9 100644 --- a/game/tests/unit/core/save_manager_domain_test.gd +++ b/game/tests/unit/core/save_manager_domain_test.gd @@ -478,7 +478,7 @@ func _smoke_save_slots() -> void: fsrc.store_string(JSON.stringify({"version": 7, "meta": {"keystone_balance": 1234}})) fsrc.close() DirAccess.remove_absolute(slot_tpl % 1) - ml.slots._migrate_legacy_save(legacy_src, slot_tpl % 1, legacy_src + ".migrated.bak") + ml.slots.migrate_legacy_save(legacy_src, slot_tpl % 1, legacy_src + ".migrated.bak") var migrated: Dictionary = JSON.parse_string(FileAccess.get_file_as_string(slot_tpl % 1)) Kit.check("sv12 旧档字节迁入槽 1(逐域相等——余额 1234)〔卡① sv12〕", int((migrated.get("meta", {}) as Dictionary).get("keystone_balance", -1)) == 1234) @@ -489,7 +489,7 @@ func _smoke_save_slots() -> void: var fsrc2 := FileAccess.open(legacy_src, FileAccess.WRITE) fsrc2.store_string(JSON.stringify({"version": 7, "meta": {"keystone_balance": 777}})) fsrc2.close() - ml.slots._migrate_legacy_save(legacy_src, slot_tpl % 1, legacy_src + ".migrated.bak") + ml.slots.migrate_legacy_save(legacy_src, slot_tpl % 1, legacy_src + ".migrated.bak") var slot1_now: Dictionary = JSON.parse_string(FileAccess.get_file_as_string(slot_tpl % 1)) Kit.check("sv12 幂等:槽 1 已存在不重迁(预置 777 零覆盖、源保留)〔卡① sv12〕", int((slot1_now.get("meta", {}) as Dictionary).get("keystone_balance", -1)) == 1234 diff --git a/game/tests/unit/data_config/forge_table_test.gd b/game/tests/unit/data_config/forge_table_test.gd index 226a5114..7bca3562 100644 --- a/game/tests/unit/data_config/forge_table_test.gd +++ b/game/tests/unit/data_config/forge_table_test.gd @@ -216,5 +216,5 @@ func _test_negative_cases() -> void: func _test_effect_kinds_closed() -> void: Kit.check("效果引擎效果类型闭集 32 种(甲案词表退役——overflow/attack_segments 摘名)〔锻造工坊批 V11〕", EffectEngineScript.EFFECT_KINDS.size() == 32) - Kit.check("效果引擎事件词表在册 22 种(迭代 46 换图系扩签 refresh_request/board_refreshed 换代)〔锻造工坊批 V11〕", - EffectEngineScript.EVENTS.size() == 22) + Kit.check("效果引擎事件词表在册 21 种(charge_full 位摘名——蓄力层删键批)〔锻造工坊批 V11〕", + EffectEngineScript.EVENTS.size() == 21) diff --git a/reports/iter51-反哺点-2026-11-04.md b/reports/iter51-反哺点-2026-11-04.md deleted file mode 100644 index a1da6912..00000000 --- a/reports/iter51-反哺点-2026-11-04.md +++ /dev/null @@ -1,29 +0,0 @@ -# 迭代 51 反哺点清单(2026-11-04) - -> 实现批禁写 `design/`——以下各条由用户裁决后归文档批落文。裁决一条落一条,落完把该条清掉。 - -## 一、design/engineering/architecture/architecture.md(十处) - -1. **:124(BattleFxHost 行)**:「A3 action_economy(queue_ap_delta/charge_layers 读)」依赖句删 charge_layers 读——蓄力层账本已退役(卡①),A3 对 action_economy 依赖余 queue_ap_delta 通道。 -2. **:146(轴戊 EffectPort 句)**:「闭面五键」改「闭面四键」;「facts 取值束 dig_streak/charge_layers/rider_tier_*」删 charge_layers——biz_fact 闭面收窄为 dig_streak/hp_ratio/rider_tier_bonus/rider_tier_crit(卡①,键退役后宿主应答 null)。 -3. **:125(RoundCycle 行)**:「三参直构(host/fx_host_ref/reward_grant_ref——五段构造透传不落成员)」→「引用束注入(编排器 20 键封闭束,解包自用七键后原束分发五段;持有 BattleRefreshFlow);公开方法 3→4(refresh_flow() 读出口);类变量 8→15(贴顶禁再增)」(卡②)。 -4. **:123(BattleRefreshFlow 行)**:「static 两入口收 oc」→「实例束注入 8 键(facts/db/action_economy/fx_host/reward_economy/minesweeper/install_cb/grant_seg);宿主 can_refresh/player_request_refresh 单行转发形态不变,经 RoundCycle.refresh_flow() 取件;grant_seg 段间引用直接交接(编排器 _rounds._grant_seg 跨两层链式取段消灭);类变量 0→8」(卡②)。 -5. **:127(settlement/ 五段段类行)**:构造形态句 →「引用束注入(各段断言各自必需键);段类对编排器零引用(\boc\b 零命中——跨件单向接线,注入 Callable 亦属接线面)」(卡②)。 -6. **:122(damage_controller 行)**:类变量 12→13(+facts 构造注入);公开面净增 hero_atk()/static hits_of()/emit_hero_damage_taken 公开化(_emit 去下划线非并存)(卡②)。 -7. **:121(RewardGrant 行)**:+feat_yield_adjust(_feat_yield_adjust 自编排器归位)(卡②)。 -8. **:120(BattleFxHost 行)**:+mark_new_resource_type/+add_bonus_delta 两公开累积方法(类变量 15 不变,方法-only)(卡②)。 -9. **核心层表 A2 minesweeper_rules 行**:公开面 19→21(贴顶超 1——**随卡② S13 停卡呈报待用户裁**:特批准记基线则登记 21 贴顶超阈值态并立还债条目;harmful_variants/harmful_adjacent 自编排器归位)(卡②)。 -10. **核心层表 breakpoint_store 行+save_manager/slot_store 行**:breakpoint_store 公开方法面 5→18(13 新面+bp_read 公开化);save_manager 公开面 7→14(+set_read_only/read_only/reset_to_default/data_snapshot/restore_data+peek_summary_at/rename_overwrite 两更名公开化);slot_store「双向公开面」(+active_path;migrate_legacy_save 公开化;反向私取 21 处清零)(卡②)。 -11. **:119(B1 battle_orchestrator 行)**:「NODE_TYPES 词表双份」表述删句、改「词表单点归 LevelTable(生成器 class_name 直引——S3 豁免面在案形态)」(卡③)。 - -## 二、GDD 确认行 - -- design/gdd/systems/战斗循环/战斗结算.md:**零反哺**(明细流水词表、五段段序、段边界零触碰——零行为变更批,golden 逐位对拍在案)。 -- design/gdd/systems/表现与支撑/数据配置.md:**零反哺**(热重载规格保留原状——P2 卡不收件面)。 -- 术语表:**零新增术语**(引用束注入/读投影/公开方法面均仓库现行词)。 -- 卡④:难度曲线与Boss.md/敌人系统.md/08-Alpha版本标准.md **零动作**(文档批已随写卡段落文,本批零新增反哺)。 - -## 三、待办清单(实现批不碰,归收尾段/用户) - -- 卡② S13 一键(minesweeper_rules 公开方法 21>20):待用户按实现报告 §六裁决;若特批准记基线,建议同批立「minesweeper_rules 公开面还债」条目归后续批。 -- EffectEngine.has_effect_on 零消费方(卡① 备案):是否立死码处置条目,归用户裁。 diff --git a/reports/iter51-实现报告-2026-11-04.md b/reports/iter51-实现报告-2026-11-04.md deleted file mode 100644 index 10c80207..00000000 --- a/reports/iter51-实现报告-2026-11-04.md +++ /dev/null @@ -1,102 +0,0 @@ -# 迭代 51 实现报告(2026-11-04) - -> 四卡:①EffectPort 蓄力层删键批 ②架构审查 5.1 封装修复批 ③架构审查 P2 代码面批 ④L1 深度 3 混编。 -> 工作区=g-plan2-iter51(分支 iter51,基点 63fe2da0);提交序列见 git log(卡① 一笔/卡② 四笔 T1+T2、T3+T4、T5、——/卡③ 一笔/卡④ 一笔)。 -> **卡② 停卡呈报在案(S13 一键待裁)**——见「六、停卡呈报」,合并等用户裁决。 - -## 一、各卡状态 - -| 卡 | 状态 | 提交 | 卡内验证读数 | -|---|---|---|---| -| ① EffectPort 蓄力层删键 | 完成 | ace15701 | effect_port_test 16 checks(含新 V4)/treasure_effects PASS/refresh_feats 85 checks;零残留 grep 达成(例外见决定记录 2);S13 零新违规 | -| ② 5.1 封装修复 | **施工完成·S13 停卡呈报待裁** | 568c474d/d43de922/0e1763bd | golden 主证改前固化改后逐位同(seed 4242,3 checks)/settle_segments 18 checks/adventure_feats 138 checks/battle_settlement 七套件绿/存档五套件绿(17+97+22+13+29)/sweep 38 checks/冒烟绿;**S13 新违规 1 条**(minesweeper_rules 公开方法 21>20 贴顶——§六) | -| ③ P2 NODE_TYPES 单点化 | 完成 | 52bb63d7 | encapsulation_p2_sweep 6 checks/node_map_determinism 21 checks(同种子逐位——零行为变更主证)/冒烟绿;S13 键零变化 | -| ④ L1 深度 3 混编 | 完成 | afaab6a7 | table_structure_guard 83 checks(v1–v6)/round_flow 136 checks(含 _smoke_enemy_buff_targets_self 种子搜索命中)/level_shop 195 checks/damage_controller 50/battle_narrator 22/config_db_test 29/config_db_resolver 13;全仓 hobgoblin 零残留(例外见决定记录 7);Alpha 零读数(静态论证) | - -## 二、实际改动—验收对照表 - -### 卡①(对照表 3 行全绿) - -| # | 需求点 | 改动 | 验收测试(落点+尾缀) | 真实入口 | 判据绑定面 | 结果 | -|---|---|---|---|---|---|---| -| 1 | 事实应答面收窄 | battle_fx_host.gd biz_fact/_fx_fact 两分支删 | effect_port_test.gd:131「V4 闭面收窄」 | begin_battle 真实装配链取宿主 biz_fact | 键在→返 0、键退役→null | 绿(16 checks 内) | -| 2 | 账本与转蓄分支退役、签名简化 | action_economy.gd finish_round_stop 纯 RAP 转存+grant_segment 调用简化 | treasure_effects_test.gd ⑥ 三断言(132/138/144 调用单参化,期望值零变) | request_stop→round_end→finish_round_stop 真实停手路径 | RAP 转存读数 4/5/3 逐位零漂移 | 绿(PASS) | -| 3 | 事件/事实两词表位退役 | effect_engine.gd EVENTS/FACTS 删位 | 静态判据+零残留 grep+S13+--code 域(合回 CI) | —(词表常量面) | 静态判据+评审注记(申报观测面局限在卡) | 绿(grep 零命中) | - -### 卡②(对照表 R1–R6 全绿,全部「非行为改动」行) - -| # | 需求点 | 改动 | 验收测试 | 真实入口 | 判据绑定面 | 结果 | -|---|---|---|---|---|---|---| -| R1 | 七段解耦+束交付 | 七文件重写+编排器 20 键束+三调用点 | settlement_wiring_snapshot_test〔封装5.1 V1〕+settle_segments_test 束构造/同一性断言+round_flow/seal_polarity/refresh_feats 既有全套 | begin_battle→settle_batch→player_request_refresh 全公开入口 | 同种子行流逐位同 golden+束引用同一性+\boc\b 七文件零命中 | 绿 | -| R2 | 搬家五方法归位 | damage_controller +hero_atk/hits_of/emit 公开化+facts;reward_grant +feat_yield_adjust;minesweeper +harmful_variants/harmful_adjacent;编排器五方法删 | golden V1(五方法消费路径全在行流内)+roll_multiplier_test 既有+sweep V3 | begin_battle/授予段真实结算链 | 行流逐位同+五方法宿主定义唯一 | 绿 | -| R3 | grant→BattleFxHost 累积方法 | battle_fx_host +mark_new_resource_type/+add_bonus_delta;grant 四处改址 | seal_polarity/round_flow 既有回归+sweep V6 | 授予段真实结算链 | bonus_delta 轴累积与首见判定逐位同+grant 源零私键 | 绿 | -| R4 | adventure_runner→BreakpointStore | breakpoint_store +13 公开方法(bp_read 公开化);adventure_runner 37 处改址 | save_rng_roundtrip_test 两断言既有+sweep V4 | resume_adventure/start_adventure→write_to_disk/load_from_disk | 断点续玩逐位同+源零私取 | 绿 | -| R5 | save_manager↔SlotStore 双向 | slot_store +active_path/migrate 公开化+21 处改址;save_manager +5 公开方法/2 更名+九行改址 | save_manager_domain_test+save_slot_isolation_test+sweep V5 | write_to_disk/load_from_disk/_ready 迁移口/activate_slot/peek_slot_summary | 写盘读回迁移激活窥视逐位同+双向源零私取 | 绿 | -| R6 | config_db→三表挂载 | 三 schema +bind_resolver;config_db 三行改址 | config_db_resolver_test 既有全套+sweep V7 | ConfigDB.load_tables→resolve_* | 行集解析与难度 clamp 逐位同+源零直写 | 绿 | - -**零行为变更证明**:T1 golden 改前基线固化(seed 4242 未改树转储 7444 字符 JSON 填入常量)、改后全程绿=行流/快照/终局载荷/presentation 逐位同;既有套件零转红;sweep 恒零。 - -### 卡③(对照表 R1 全绿) - -| # | 需求点 | 改动 | 验收测试 | 真实入口 | 判据绑定面 | 结果 | -|---|---|---|---|---|---|---| -| R1 | NODE_TYPES 单点化 | node_map_generator :10 删+:135 改 LevelTable.NODE_TYPES.has | encapsulation_p2_sweep_test〔架构P2 V1/V2〕+node_map_determinism_test 既有全套 | LevelRunner 关卡推进→节点图生成;LevelTable 表行加载校验 | 词表定义唯一落点(正锚计数=1)+生成链同种子逐位同 | 绿 | - -### 卡④(对照表 R1–R10 全绿) - -| # | 需求点 | 改动 | 验收测试(尾缀〔L1混编 vN〕) | 真实入口 | 判据绑定面 | 结果 | -|---|---|---|---|---|---|---| -| R1 | 行数与键序 | enemy.tres (1,3) 一行换两行 | table_structure_guard「敌人表 29 行且键序=覆盖表序((1,3) 两行相邻、熊地精在前)」 | ConfigDb.load_tables→EnemyTable.rows | 遍历 rows 拼四段串逐行比对 | 绿(83 checks 内) | -| R2 | 混编构成与行序 | 同上 | 同文件「(1,3) 行集恰两行、enemy_id 序列==[bugbear,goblin]」 | resolve_rowset(1,3,"battle") | 返回长度与 enemy_id 序列 | 绿 | -| R3 | 静态最坏骰和 | 同上 | 同文件「Σ(unit_count_max,固定行缺省)==3」 | 同上 | 求和值==3 | 绿 | -| R4 | 行值整行复用 | 同上 | 同文件「(1,3) 两行逐字段==(1,2)/(1,0) 行」 | EnemyTable.rows | 字段逐项比对零字面量 | 绿 | -| R5 | 零残留 | 表+七文件 | 同文件「表内 enemy_id 集合不含 hobgoblin」+T2 回读命令 | rows 遍历+grep | 集合不含+grep 空 | 绿 | -| R6 | 混编下 spawn 数全域内 | round_flow :312-317 口径逐行求和 | _smoke_encounter_roll 全深度×12 种子扫描 | begin_battle→presentation_snapshot().enemies.size() | 逐场数量∈[Σunit_count,Σunit_count_max] 且 ≥1 | 绿(136 checks 内) | -| R7 | 双池各自独立 | 表两行 | _smoke_skill_pool_data「(1,3) 两行池模板」 | 表读取 | 键与权重逐项 | 绿 | -| R8 | 注入段还原行数 | level_shop :727 | _smoke_level_graph「表回 29 行」 | 同套件注入/还原流程 | rows.size()==29 | 绿 | -| R9 | 深度 4/5 落带不变 | 表(零触碰) | table_guard「(1,4)/(1,5) battle 行集==单行 bugbear(band 6)」 | resolve_rowset(1,4/5) | 长度与 enemy_id、band 归属 | 绿 | -| R10 | 深度 3 最少 2 敌(回归护栏) | 两处夹具注释 | damage_controller_test _test_pool_consumption_per_unit+battle_narrator_test _test_snapshot_effects_per_unit 在混编行集下仍绿 | UnitContainer.spawn(1,3) | all_enemies().size()≥2 | 绿 | - -## 三、S13 对账 - -- 改前基线:gdstyle_gate 5 键基线内、基线外 0(T1 现场读数;adventure_runner 类变量 23 照登)。 -- 改后:**基线外新违规 1 条=game/core/minesweeper_rules.gd|quality/max-public-methods(21>20 贴顶)**——卡② 停卡呈报项(§六)。其余全部触件 S13 键只降不升:action_economy 删 2 成员、七段束解包全在预算内(grant 12/combat 10/verdict 5/aura 1/decay 2/round_cycle 15 贴顶/battle_refresh_flow 8)、breakpoint_store 类变量 15 贴顶方法-only、编排器 15 不变。 - -## 四、实机目检总清单(真人检测只登记不阻塞) - -- 卡①②③:无实机目检项(死码删除/封装收口/词表单点化——零玩家可观测提交面;卡② 零行为变更由 golden 逐位对拍承载)。 -- 卡④(抄体验验证清单 ⑱ L1 节点 3 三项):① 混编遭遇实机目检(L1 节点 3 遇敌=熊地精 1+地精 1–2,默认目标=熊地精);② 开战叙述首行=熊地精;③ 战斗结算面两种数量语义并存目检。读数义务:Alpha 零读数(2026-11-04 用户裁),带位移读数归数值统一修正批。 - -## 五、能力清单核对 - -game/tests/README.md:本批零编辑(四卡对照表能力行全部「既有」;测试函数名零改名——settle_segments/round_flow/level_shop/damage_controller/battle_narrator 代表用例名在册不变;卡② 新增两测试件按「经宿主链覆盖」申报=snapshot 测试挂 R1 行 begin_battle 全结算链、sweep 挂各 R 行源扫描)。名实核对一致,无回表项。 - -## 六、停卡呈报(卡② S13 一键——实现段零裁断,缺陷移交) - -**分歧点**:minesweeper_rules.gd 公开方法数。写卡 §14 申报「18→20 贴顶(+2)」;master 基点实数 **19**(`git show master:game/core/minesweeper_rules.gd` 逐 func 清点),本批 +2 搬家方法(harmful_variants/harmful_adjacent)后 **21>20**(S13 默认阈值)——gdstyle_gate 基线外新违规 1 条。 - -**两种读法**: -- 读法 A(写卡考证误差 1,预算按实况校准为 19→21):+2 是卡② 五方法归位裁决的直接后果(grant_segment :87/:339 两消费方直调,两方法都必须公开,少任何一件破坏搬家合同);21 超阈值需用户特批准记基线(迭代 38 先例 c4c69701——S13 恶化经用户特批准记入基线存量红)。但 static_scan S13 头注「登记值只准随还债下降,禁抬高到现状」——特批是唯一合法通道,闸件纪律不因批内需要自动放行。 -- 读法 B(卡面预算准、实现走形):不存在第三形态——拆函数降计数=实现段自行拆件(L3 ③禁);改闸件豁免=禁(卡② §13;先例迭代 38 卡② 停卡);把方法挪去 BoardData 或他件=职责面重设计(上游裁决)。 - -**建议案**:读法 A——用户特批准记基线 1 键(minesweeper_rules 公开方法 21),理由:+2 归位是 2026-11-03 会话裁决的机械承载、消费面决定两方法必须公开、基点考证误差 1 属写卡段缺陷(非实现超预算)、特批有迭代 38 先例。批后可开「minesweeper_rules 公开面还债」条目(归后续批:如 settle_batch/fx_reveal 族收敛)随还债降键。 - -**该红不阻塞的实证**:卡② 全部验收断言绿、golden 零漂移、sweep 恒零——S13 是结构预算闸不是行为闸;红项单键、修复路径已指认(特批记基线或后续还债批)。用户裁决后本迭代即可走独立验收审计→合并;若用户裁读法 B(拆面),开修复 worktree `fix-iter51-s13` 处置后重审计。 - -## 七、实现决定记录(代拍板白名单外备案) - -1. **卡① has_effect_on 零消费方保留**:删 grant_segment 调用后 `EffectEngine.has_effect_on` 全仓零调用。卡面 :203 处置=注释改写、函数保留(T0 步骤明写「:203 句改……」未列函数删除),未代裁扩大删除面。后续可另立待办处置(纯框架 API 死码)。 -2. **卡① 零残留 grep 唯一例外**:effect_port_test.gd:131 V4 断言文案与 `biz_fact("charge_layers")` 参数引证退役键名——卡面 T0 定死的断言文案(证明「键退役→null」必须引用键名),断言优先于 grep 字面。 -3. **卡① 三处 swap 域描述词换代**:run_all.gd:213 manifest 注释、effect_port_test :67/:83 的「蓄力层」简称改「蓄力周转」(swap_charge_layers 在役域,词面清旧称;断言判据零变——:83 属断言文案措辞,判据 `v_c - v_0 >= 1` 不动)。 -4. **卡② oc._ 计数 102 vs 卡面 105**:迭代 50 甲案删 attack_segments 分支所致(卡面预告的漂移,grep 符号锚定位,禁改判据)。 -5. **卡④ 曲线护栏逐带累加**:table_structure_guard_test 第一关总量比断言原单行覆盖口径在 (1,3) 双行同带下失真(后行覆盖前行→band3 总量 12→72 比值 6.00 假红);改同带逐行累加(band3=22×1+8×1.5=34,比值 2.12)——与卡④ R6 已裁「逐行求和与 spawn 守卫同口径」同构,阈值 2.5 零变化,非放宽。期望序列文案 12/10/22/35/72→12/10/22/34/72(34=混编实况)。 -6. **卡④ level_shop 白盒抬 GP**:(1,3) 混编改战斗流随机消费序→_smoke_shop_pool 种子扫描选中的场景 gp 分布漂移(进店刷新扣费后 gp=1<全架最低价)→「可购卡在架」假红。修法=③ 买段前白盒 `r8.gp += 128`(A 银段 :1345 同款先例「直改测试基建——非生产行为」),买链判据零变化;MC-1 刷新段保持原位(进店未买态语义),未动段落序。 -7. **卡④ R5 零残留 grep 唯一例外**:table_structure_guard_test 新增 v5 断言文案与 `id_set.has("hobgoblin")` 引证退役键名(卡面 §八 R5 定死验收文案)。 -8. **卡② 测试连带三处迁移**(写卡 §3.2 漏盘点):adventure_feats_test :791 与 level_shop_economy_test :1484 `a._bp_store._pending_next_level` → `pending_next_level()`;feat_vouchers_test :81 `_loadout_seeded = false` → `set_loadout_seeded(false)`(断点公开面在用,引用形态迁移非削弱);damage_controller_test :55 直构夹具补 BattleFacts 第五参(facts 构造注入——hero_atk 消费面,夹具空 encounter=表值缺省)。**审计订正**:level_shop 一处曾随回滚实验丢失(卡④ 提交后由独立验收审计查出,:1484 补迁移复跑 195 checks 绿——动态访问失效成员使停点分支恒假、依赖种子被扫描跳过掩盖红,属申报落实的漏项非削弱)。 -9. **卡② snapshot 测试对拍形态**:GOLDEN 三引号 raw string 首尾各带换行(多行字符串语法载体),比较两侧 strip_edges 后逐位等——判据零变(内容逐位),语法载体适配。 - -## 八、遗留读数义务与反哺点 - -- 遗留读数:卡④ Alpha 零读数(归数值统一修正批);卡② S13 一键(§六待裁)。 -- 反哺点:见 `reports/iter51-反哺点-2026-11-04.md`(architecture.md 十处+GDD/术语确认行)。 -- 待办清单条目状态推进与 roadmap「当前位」换代:归文档批(本批禁写)。 diff --git a/reports/iter51-验收审计-2026-11-04.md b/reports/iter51-验收审计-2026-11-04.md deleted file mode 100644 index 3cdafe66..00000000 --- a/reports/iter51-验收审计-2026-11-04.md +++ /dev/null @@ -1,190 +0,0 @@ -# 迭代 51 独立验收审计(2026-11-04) - -> 审计身份:独立会话审计员,未参与本批实现(实现由另一会话完成)。 -> 工作区:D:\code\g-plan2-iter51(分支 iter51,基点 master=63fe2da0,diff 范围 63fe2da0..HEAD,HEAD=ef3cd8db,工作树 clean)。 -> 审计范围:四张需求卡片(①EffectPort 蓄力层删键批 ②架构审查 5.1 封装修复批 ③架构审查 P2 代码面批 ④L1 深度 3 混编)+实现报告 §一–§八+全量 diff 逐文件核对(48 件,+1594/−474)。 -> **验收档:四卡均未申报验收档——按高档全量执行**(对照表逐行核对+判据绑定面抽查+最窄测试复跑抽查+逐处削弱检查+直查例外核对+S13 对账复核)。 -> 纪律:只读生产码与测试;禁变异类测试、禁撤销类取证;本报告为本审计唯一写入文件。 - -## 一、最窄测试复跑读数 - -环境:Godot 4.7.2 console 版(D:\code\godot\Godot_v4.7.2-stable_win64_console.exe)headless,工作目录 game/,`--script` 单件直跑;跑前确认 `game/.godot/global_script_class_cache.cfg` 在位(直接跑)。退出码 0=绿。 - -| 套件 | 归属 | 退出码 | 读数 | -|---|---|---|---| -| effect_port_test | 卡① V4(五件套) | 0 | all green(16 checks,V4 断言在列全 PASS) | -| settlement_wiring_snapshot_test | 卡② R1 golden 主证(五件套) | 0 | all green(3 checks,golden 逐位同) | -| encapsulation_sweep_test | 卡② V2–V7(五件套) | 0 | all green(38 checks) | -| encapsulation_p2_sweep_test | 卡③ V1/V2(五件套) | 0 | all green(6 checks) | -| table_structure_guard_test | 卡④ v1–v6(五件套) | 0 | all green(83 checks,v1–v6 六条全 PASS) | -| round_flow_skill_pool_test | 审计自选(卡④ R6/R7/R10) | 0 | all green(136 checks,含 buff_targets_self 种子搜索命中 seed=1) | -| save_rng_roundtrip_test | 审计自选(卡② R4) | 0 | all green(17 checks) | -| treasure_effects_test | 卡① 行 2 | 0 | PASS | -| settle_segments_test | 卡② R1 | 0 | all green(18 checks) | -| adventure_feats_test | 卡② R2 | 0 | all green(138 checks) | -| seal_polarity_test | 卡② R3 | 0 | all green(70 checks) | -| refresh_feats_test | 卡① 契约 2/卡② R1 | 0 | all green(85 checks) | -| roll_multiplier_test | 卡② R2 | 0 | all green(42 checks) | -| config_db_resolver_test | 卡② R6/卡④ | 0 | all green(13 checks) | -| config_db_test | 卡④ | 0 | all green(29 checks) | -| save_manager_domain_test | 卡② R5 | 0 | all green(97 checks) | -| save_slot_isolation_test | 卡② R5 | 0 | all green(22 checks) | -| feat_vouchers_test | 卡② 连带迁移 | 0 | all green(49 checks) | -| damage_controller_test | 卡④ R10 | 0 | all green(50 checks) | -| battle_narrator_test | 卡④ R10 | 0 | all green(22 checks) | -| level_shop_economy_test | 卡④ R8 | 0 | all green(195 checks) | -| node_map_determinism_test | 卡③ 零行为主证 | 0 | all green(21 checks) | - -## 二、卡① EffectPort 蓄力层删键批 - -### 对照表逐行核对(3 行) - -| 行 | 验收测试存在性 | 尾缀 grep | 真实入口判定 | 结果 | -|---|---|---|---|---| -| 1 | effect_port_test.gd:131 断言在(V3 组 `_test_biz_fact_face_closed` 末尾) | 「V4 闭面收窄:charge_layers 键退役——宿主事实应答 null」grep 命中 :131 | begin_battle 真实装配链(:102 `orch.begin_battle(_enc([]))` 受理后 :131 取 `orch.fx_host().biz_fact("charge_layers")`——fx_host() 公开访问器+biz_fact 公开方法,未绕过装配链直调下层) | 通过 | -| 2 | treasure_effects_test 三断言在,期望值 rap==4/5/3 逐字未动(diff 仅调用实参行) | 无新增尾缀(既有断言回归锚,卡面即如此定) | request_stop→finish_round_stop 真实停手路径;直构 ActionEconomy 夹具=卡面 §8 测试方式两分法明示的调试接口验证形态,且卡面 §7 T0 逐字定死该三行改单参——非绕过 | 通过 | -| 3 | 静态判据:effect_engine.gd EVENTS `charge_full` 位、FACTS `charge_layers` 位删除(diff 证实 :14/:59 两处删位) | —(词表常量面,卡面明示无独立运行期提交面) | —(静态判据+评审注记,卡面申报观测面局限在案) | 通过 | - -零残留复核:`grep -rn "charge_layers|charge_full|CHARGE_LAYER|蓄力层|转蓄力|厚积薄发|铁壁|整备军备" game/ --include=*.gd --include=*.tres` 全部命中仅在 swap_charge_layers 在役域(feats.tres :1018-1056 六行、refresh_feats_test `test_charge_layers_consumed_same_round` 函数名与其断言、effect_port_test :16 注释)+V4 断言键名引证(effect_port_test :131)——前者=卡面 §1 完成定义明写豁免域,后者=报告决定记录 2 申报的唯一例外(证明「键退役→null」必须引用键名)。达卡面 T1 零残留判据。 - -### 削弱检查(逐处) - -| diff 处 | 申报出处 | 结论 | -|---|---|---| -| treasure_effects_test 三处 finish_round_stop(false,N)→(N)(:132/:138/:144) | 卡① §8 测试削弱申报 | 通过——断言期望值与检查语义逐字零变化 | -| effect_port_test :57 注释+:83 断言文案「蓄力层→蓄力周转」 | 卡① §8 申报(V1 两处文案) | 通过——判据 `v_c - v_0 >= 1` 不动 | -| effect_port_test :16/:103 误标注释改写 | 卡① §7 T1 申报(三处注释) | 通过——注释级 | -| run_all.gd:213 manifest 注释「蓄力层→蓄力周转」 | 报告决定记录 3 | 通过——注释级,判据零变 | -| has_effect_on 函数保留(grant_segment 调用删后全仓零调用方) | 报告决定记录 1(卡面 T0 :203 只列注释改写、未列函数删除) | 通过——未代裁扩大删除面,与卡面一致 | - -无未申报删改。 - -### 直查例外核对 - -对照表三行均未声明「内部字段直查=受控例外」:行 1 走公开面(fx_host()/biz_fact);行 2 直构夹具=卡面 §8 两分法明示形态;行 3 静态面。无需例外注记,判定=通过。 - -## 三、卡② 架构审查 5.1 封装修复批 - -### 对照表逐行核对(R1–R6) - -| 行 | 验收测试存在性 | 尾缀 grep | 真实入口判定 | 结果 | -|---|---|---|---|---| -| R1 | settlement_wiring_snapshot_test.gd:456 主对拍在(GOLDEN 常量 :22-416 固化,seed 4242;dump 通道 :443-448);settle_segments_test :30-34 束构造 5 条+:38-44 同一性 6 条在 | 「封装5.1 V1」:4/:456 命中 | begin_battle→minesweeper.settle_batch→player_request_refresh 全公开入口;段类消费全经真实编排器接线(settle_segments 直构束=卡面 §8 申报 1 的适配形态) | 通过 | -| R2 | golden V1 覆盖五方法消费路径(主角攻击 base_value/奖励乘区/terrain_kind 事实/hero_atk override 行均在 golden 行流内);roll_multiplier_test 既有回归绿;sweep V3 编排器五方法定义零命中 | sweep :69-70 五方法名零命中断言(〔封装5.1〕尾缀 :36/:42 模板命中 38 处) | begin_battle spawn 经 `_damage.hero_atk()`(battle_orchestrator.gd diff :285 证实改指),未绕过 | 通过 | -| R3 | seal_polarity_test 70 checks/round_flow 136 checks 绿+sweep V6(grant 两私键零命中+mark_new_resource_type 正锚 :100-101) | 〔封装5.1〕尾缀在案 | 授予段真实结算链(两套件全走 begin_battle) | 通过 | -| R4 | save_rng_roundtrip_test diff 零改动(未触碰)、17 checks 绿;sweep V4(adventure_runner `_bp_store\._` 零命中+`_bp_store\.bp_read\(` 正锚 :78-79) | 〔封装5.1〕尾缀在案 | AdventureRunner.resume_adventure/start_adventure→write_to_disk/load_from_disk(integration 件真实入口) | 通过 | -| R5 | save_manager_domain_test 97/save_slot_isolation_test 22 绿;sweep V5(save_manager `slots\._` 零命中+active_path 正锚;slot_store `_save\._` 零命中+七公开面正锚 :84-92) | 〔封装5.1〕尾缀在案 | write_to_disk/load_from_disk/_ready 迁移口/activate_slot/peek_slot_summary(两套件承载) | 通过 | -| R6 | config_db_resolver_test 13 checks 绿(rowset 保序/行类路由/难度 clamp);sweep V7(config_db `\._resolver\s*=` 零命中+`bind_resolver\(_resolver\)` 正锚 :109-110) | 〔封装5.1〕尾缀在案 | ConfigDB.load_tables→resolve_*(三 schema bind_resolver 类型环当轮真实跑通——T4 义务承载) | 通过 | - -零行为变更主证复核:golden 对拍断言绿(本审计复跑);段类对编排器引用归零由 sweep V2 七文件 `\boc\b` 零命中承载;束 20 键组装与五方法删除、RoundCycle/BattleRefreshFlow 形态换代在 diff 逐文件证实。 - -### 削弱检查(逐处) - -| diff 处 | 申报出处 | 结论 | -|---|---|---| -| settle_segments_test :20-24 五段直构断言改束构造成功(:30-34) | 卡② §8 申报 1 | 通过——段类可独立实例化断言意图保持 | -| settle_segments_test :28-34 宿主回指 6 条改注入同一性(:38-44——round_cycle.facts/grant.facts/aura 回调对象 get_object()==oc/combat.fx_host/decay.status_effects/verdict.units) | 卡② §8 申报 2 | 通过——6 条全数对上,强度对应回指 | -| adventure_feats_test :671/:691/:727 三处 orch._hits_of→DamageController.hits_of | 卡② §8 申报 3 | 通过——断言内容(attack_bonus 命中过滤)零改动 | -| adventure_feats_test :791 `a._bp_store._pending_next_level`→`pending_next_level()` | 报告 §七 8 | 落地证实(grep 现值为公开方法调用) | -| feat_vouchers_test :81 `_loadout_seeded = false`→`set_loadout_seeded(false)` | 报告 §七 8 | 落地证实 | -| damage_controller_test :56 直构夹具补 BattleFacts 第五参 | 报告 §七 8 | 通过——夹具空 encounter=表值缺省,断言零改动 | -| snapshot 测试 strip_edges 对拍(:449-451) | 报告 §七 9 | 通过——内容逐位判据零变,三引号语法载体适配 | -| **level_shop_economy_test :1484 `a._bp_store._pending_next_level`——报告 §七 8 与卡④ commit信息均申报为已迁移,实际未改** | —— | **申报失实,见第六节;非削弱(该行零改动=零删改)** | - -无未申报删改、无阈值放宽、无扫描面缩小。 - -### 直查例外核对 - -settle_segments_test 直查 `oc._facts`/`oc._rounds._grant_seg.*` 等编排器内部(同一性断言)=卡② §5 明示受控例外(「sim/probe/tests 的测量面直构惯例与测试受控例外——零清扫:orch._facts/orch._rounds/orch._emit_row 等测试直连维持现状」)。报告 §七 8 三处测试直连迁移=附加申报(其中一处未落地,见第六节,且该处属同一受控例外面、运行态零差异)。例外均有注记,判定=通过。 - -## 四、卡③ 架构审查 P2 代码面批 - -### 对照表逐行核对(R1) - -| 行 | 验收测试存在性 | 尾缀 grep | 真实入口判定 | 结果 | -|---|---|---|---|---| -| R1 | encapsulation_p2_sweep_test V1(:40-41 生成器 `^const NODE_TYPES` 零命中+`LevelTable\.NODE_TYPES\.has\(` 正锚)/V2(:56-58 生产三目录 `NODE_TYPES` 定义恰 1 处且落 data/schemas/level_table.gd);node_map_determinism_test 既有全套 21 checks 绿 | 「〔架构P2〕」尾缀 :27/:32/:56/:58 命中 | 源扫描(静态)+LevelRunner 关卡推进生成链(determinism 同种子逐位——零行为变更主证) | 通过 | - -生产面独立复核:`grep -rnE "NODE_TYPES\s*:?\s*=" core data presentation` 唯一命中 data/schemas/level_table.gd:11;node_map_generator.gd 本地 const 删、:135 改 `LevelTable.NODE_TYPES.has(...)`(diff 证实);S3 schema class_name 直引豁免面形态(卡面 §3 在案)。 - -### 削弱检查 - -卡面 §8 申报零条;diff 中本卡测试改动仅新增 sweep 件+run_all manifest +1 行——零删改既有断言。通过。 - -### 直查例外核对 - -纯源扫描与既有套件回归,无内部字段直查。通过。 - -## 五、卡④ L1 深度 3 混编 - -### 对照表逐行核对(R1–R10) - -| 行 | 验收测试存在性 | 尾缀 grep | 真实入口判定 | 结果 | -|---|---|---|---|---| -| R1 | table_structure_guard_test :232 v1(29 行键序=(1,3) 两行相邻、熊地精在前) | 〔L1混编 v1〕:232 命中 | ConfigDb.load_tables→EnemyTable.rows 遍历拼四段串逐行比对 | 通过 | -| R2 | :242 v2(行集恰两行、enemy_id 序列==[bugbear,goblin]) | 〔L1混编 v2〕:242 命中 | `resolve_rowset(1,3,"battle")` 返回序列——判据绑返回长度与 enemy_id 序列(被测数据改动特有提交面) | 通过 | -| R3 | :244 v3(Σ(unit_count_max,固定行缺省)==3) | 〔L1混编 v3〕:244 命中 | 同上求和值==3 | 通过 | -| R4 | :258 v4(两行逐字段==(1,2)/(1,0) 行,零字面量) | 〔L1混编 v4〕:258 命中 | EnemyTable.rows 字段逐项比对 | 通过 | -| R5 | :263 v5(表内 enemy_id 集合不含 hobgoblin)+T2 回读命令 | 〔L1混编 v5〕:263 命中 | rows 遍历+grep | 通过 | -| R6 | round_flow :320 全域扫描逐行求和(72 场全绿) | 断言文案「逐行求和」:320 命中 | begin_battle→presentation_snapshot().enemies.size() | 通过 | -| R7 | round_flow :575-576 池模板两键(bugbear 6/2/2+goblin 9/1/1,顺序按表行序) | :575-576 两键在案 | 表读取逐键逐权重比对 | 通过 | -| R8 | level_shop :727「表回 29 行」 | :727 断言在案 | 同套件既有注入/还原流程(rows.size()==29) | 通过 | -| R9 | :270 v6((1,4)/(1,5) battle 行集==单行 bugbear(band 6)) | 〔L1混编 v6〕:270 命中 | resolve_rowset(1,4/5,"battle") | 通过 | -| R10 | damage_controller_test _test_pool_consumption_per_unit/battle_narrator_test :114-115 _test_snapshot_effects_per_unit 混编行集下绿(50/22 checks) | —(回归护栏行,卡面即不设新尾缀) | UnitContainer.spawn(1,3)→all_enemies().size()≥2 | 通过 | - -行值整行复用独立复核:enemy.tres (1,3) bugbear 行(:82-104)与 (1,2) 行(:58-80)逐字段一致(hp22/atk1/atk 0-2/池 attack6-charge2-heavy2/normal/light/ac2/unit_count 1 无 unit_count_max);(1,3) goblin 行(:106-129)与 (1,0) 行(:8-31)逐字段一致(hp8/池 attack9-lunge1-desperate_guard1/normal/light/ac0/unit_count 1-2)。行序 bugbear 在前、两行相邻。表注四处处置(实体名修正段删/首批投放段尾追加/N1 括注保留/缺口句换新注)diff 逐处证实。零残留复核:全仓 `hobgoblin` grep(data/core/presentation/probe/sim/tests/tools)唯一命中=v5 断言自身键名引证(table_structure_guard_test :259 注释+:263 断言)=报告决定记录 7 申报的唯一例外。 - -### 削弱检查(逐处) - -| diff 处 | 申报出处 | 结论 | -|---|---|---| -| table_guard :234-241 hobgoblin 留任断言删(原〔fv12〕) | 卡④ §十二 申报① | 通过——钉已退役事实;原位换 v2–v6 五条新断言,覆盖强度净增 | -| round_flow :312-317 首行区间改逐行求和 | 卡④ §十二 申报② | 通过——与 unit_container spawn 守卫同口径,72 场全绿,双行行集下非放宽(旧口径必红) | -| round_flow :615 文案二十八行九种→二十九行十种 | 卡④ §十二 申报③ | 通过——只改文案不改判据 | -| static_scan.sh 删 FNR==891 豁免(:145 头注+:222 执行点) | 卡④ §十二 申报④ | 通过——对象行已随表注段删除,留置会误放别行 | -| 曲线护栏单行覆盖口径改逐带累加(期望序列 12/10/22/35/72→12/10/22/34/72,阈值 2.5 不动) | 报告 §七 5 | 通过——(1,3) 双行同带下旧「后行覆盖前行」口径失真(band3 总量 12→72 比值假红),新口径=同带逐行累加、与 R6 逐行求和同构;阈值零变化 | -| level_shop :1314-1324 白盒抬 GP 128+文案改 | 报告 §七 6 | 通过——测试基建直改(A 银段 :1345 同款先例在案),买链判据零变化 | -| config_db_resolver_test 合成行 hobgoblin→giant_spider(:44,三条期望串同步) | 卡④ §七 T2 明写(并明写不换 bugbear 的理由) | 通过——夹具级,断言结构零变 | -| config_db_test :222 「不相邻」样本换 giant_spider | 卡④ §七 T2 明写 | 通过——同上 | -| damage_controller_test :414/battle_narrator_test :114 两处夹具注释改述 | 卡④ §七 T2 明写(断言零改动) | 通过 | -| doc_term_audit.py :144 注释敌种枚举去 hobgoblin | 卡④ §七 T2 明写 | 通过——注释级 | - -无未申报删改、无阈值放宽、无未申报扫描面缩小。 - -### 直查例外核对 - -卡④ 判据全部绑公开面(rows/resolve_rowset 返回序列/presentation_snapshot/UnitContainer.spawn)——无需例外注记。通过。 - -## 六、申报失实项(非验收缺漏,需订正) - -**实现报告 §七 第 8 条与卡④ commit afaab6a7 提交信息均申报「卡②断点公开面三处测试直连迁移(pending_next_level×2/loadout_seeded)」,实际落地两处:** - -- adventure_feats_test :791 `a._bp_store.pending_next_level()`——已落地; -- feat_vouchers_test :81 `a._bp_store.set_loadout_seeded(false)`——已落地; -- level_shop_economy_test :1484 `if a._bp_store._pending_next_level:`——**未改**(该文件 diff 全量核对仅 :724-727 与 :1314-1324 两处触碰)。 - -定性与影响:非验收缺漏——该行零改动=无断言删改、无削弱;测试侧 `_bp_store._` 直查属卡② §5 明示受控例外面;BreakpointStore `_pending_next_level` 成员保留(breakpoint_store.gd:60),运行态与改前逐位同,套件全绿(level_shop 195 checks)。但实现报告与提交信息的该条申报与实况不符,构成产出物事实错误——建议订正实现报告 §七 第 8 条(改为「两处落地、level_shop 一处未迁」);commit 信息不可改,以本节记录在案。 - -## 七、S13 对账复核 - -实测 `python tools/gdstyle_gate.py`(工作目录 game/,退出码 1): - -``` -[gdstyle_gate] 扫描面 158 个 .gd;命中 6 条,基线内 5 条,基线外新违规 1 条,较登记值恶化 0 条 - FAIL 新增 game/core/minesweeper_rules.gd|quality/max-public-methods -[gdstyle_gate] FAIL — 基线外新违规 1 条/恶化 0 条——新码须修到基线口径内,恶化须还债或经用户批准随批重生成基线 -``` - -与实现报告 §六 逐字一致。独立考证:基点 63fe2da0 的 minesweeper_rules.gd 公开方法实数 19(`git show 63fe2da0:game/core/minesweeper_rules.gd` 逐 func 清点);HEAD 21(含新增 harmful_variants/harmful_adjacent 两搬家方法,diff :58/:70 证实)→ 21>20(S13 默认阈值)。其余触件只降不升(action_economy 类变量 14→12 实测;gdstyle 无第二键恶化)。 - -该项为实现报告 §六已停卡呈报待用户裁的结构闸项(写卡考证 18 失实、基点实数 19、+2 搬家方法),**不属于验收闭合缺陷**——本审计如实记录其状态与呈报位置,不计入审计终判。**合并前置条件=用户对该键的裁决**(特批准记基线随还债降键,或裁实现报告 §六读法 B 开 fix-iter51-s13 修复批后重审计)。 - -## 八、终判 - -**通过**——四卡对照表全部行(卡① 3 行/卡② R1–R6/卡③ R1/卡④ R1–R10)验收断言真实存在、尾缀可 grep 定位、真实入口未绕过被测改动点、判据绑被测改动特有的可观测提交面;最窄复跑五件套+审计自选两件+对照表引用全部其余套件绿(22 件全 0 退出码);测试削弱全部落在四卡申报清单与实现报告决定记录内,零未申报删改;直查例外均有注记;卡① 蓄力层族与卡④ hobgoblin 零残留 grep 达成且例外均为申报例外。 - -记录在案三项(均不改变终判): - -1. **S13 一键**(minesweeper_rules 公开方法 21>20)——停卡呈报在案(实现报告 §六)。**合并前置条件=用户对该键的裁决**;裁决后按既定通道走。 -2. **申报失实一项**——实现报告 §七 第 8 条「三处测试直连迁移」实际落地两处(level_shop_economy_test :1484 未迁),建议订正报告;非验收缺漏、非测试削弱。 -3. 卡② golden 改前固化读数以 GOLDEN 常量在案(settlement_wiring_snapshot_test.gd:22-416,seed 4242),改后对拍绿——对拍读数在案义务已履行。 diff --git a/roadmap.md b/roadmap.md index a0626c47..3f2db098 100644 --- a/roadmap.md +++ b/roadmap.md @@ -5,8 +5,8 @@ ## 当前位(只回答「现在该做什么」;三行内随批次换代,禁止在此扩写成状态快照) - **阶段**:M3——Alpha 版本的完整实现(2026-10-09 立规:未明令宣布完成前停留 M3,迭代只排 M3 需求,M4 不排期;根目录 stage.txt 为旧阶段开关仅存档)。 -- **迭代位**:迭代 1–50 全部已完成——迭代 50(敌方状态个体化+断言补齐+架构审查 3.1+3.2 整改三卡)2026-11-03 合回(合并提交 8d3a12ec,独立验收审计两轮终判通过〔首轮缺漏三条→整改笔 6cb1cf5e→复验通过〕),批后收尾闭合(2026-11-03):反哺点十条处置闭合(增益状态 v1.6 删「实装随该批」过时行/architecture v1.32 排雷规则件 preview_reveal 只读预览口登记+天赋树 tree_rules 参数字典 API 换代/奇物 v1.5 cap 必填与取值域写入/覆盖域表减动效行翻已覆盖;SPAWN_AREA_CELLS、shop.spend_discount 表字段、battle_driver 签名三处零登记零落点,天赋树 v0.12 等五份与术语表零反哺确认)、实机目检五项登记体验验证清单 ㊿〔实现报告原编㊾与 CI 迁远端批撞号,改用㊿〕、MC 锚代表性注记落 sim-data/README(重跑归一档用户发起)、产出物退役六件(三需求卡片+反哺点+实现报告+验收审计——吸收即死+证据只留最新)、待办清单三卡条目整条删除(架构审查余项〔审计待裁点④⑤⑥⑦〕按未决先迁再死另立新条登记)。迭代 49 收尾记录见 git 提交 aa396eb9,迭代 48 见 bd54d1f4。 -- **下一步**:迭代 51 已编入待开工(四卡 ≈6.625 工作日,`/iter 51` 发令)。待编池:改写族孤儿(待处置方向裁决)、二三关棋盘观感(待设计+待美术)、EC8 热重载实装(待用户另立条目)。 +- **迭代位**:迭代 1–51 全部已完成——迭代 51(四卡:EffectPort 蓄力层删键/架构审查 5.1 封装修复/P2 NODE_TYPES 词表单点化/L1 深度 3 混编)2026-11-04 合回(合并提交 fb27dc2f,独立验收审计终判通过),批后收尾闭合(2026-11-04):反哺点十条落文 architecture.md(第十一条落点不存在跳过、呈报在案)+S13 无凭证基线键经用户裁撤销(--refresh 重生成入口同批删除、基线改人工修订,gdstyle 红在案由还债 P0 追绿)+还债与死函数清退两条 P0 登记+presentation 卡未编迭代迁出承接条目+产出物退役三件+待办三条目删除。迭代 50 收尾记录见 git 提交 47c752ea,迭代 49 见 aa396eb9。远端 CI:run 51/52 红(runner 中断非闸红)、run 53–55 排队待 Mac 上线。 +- **下一步**:P0 两条待写卡(minesweeper_rules 公开面还债——gdstyle 红在案追绿;EffectEngine 死函数与全仓孤儿函数清退);presentation 层封装修复卡已写卡待编迭代(4.125 工作日)。待编池:改写族孤儿(待处置方向裁决)、二三关棋盘观感(待设计+待美术)、EC8 热重载实装(待用户另立条目)。 ## 里程碑时间线 @@ -84,7 +84,7 @@ | 迭代 48 | 已完成(2026-11-02) | 已退役(git 历史可考) | 2026-11-01 | ≈6.1 个工作日 | 已退役(git 历史可考) | | 迭代 49 | 已完成(2026-11-02) | 已退役(git 历史可考) | 2026-11-02 | ≈7.25 个工作日 | 已退役(git 历史可考) | | 迭代 50 | 已完成(2026-11-03) | 已退役(git 历史可考) | 2026-11-03 | ≈12.875 个工作日〔用户特批 2026-11-03 超 10 个工作日〕 | 已退役(git 历史可考) | -| 迭代 51 | 待开工 | reports/需求卡片-EffectPort蓄力层删键批-2026-11-04.md
reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md
reports/需求卡片-架构审查P2代码面批-2026-11-03.md
reports/需求卡片-L1深度3混编-2026-11-04.md | 2026-11-04 | ≈6.625 个工作日 | — | +| 迭代 51 | 已完成(2026-11-04) | 已退役(git 历史可考) | 2026-11-04 | ≈6.625 个工作日 | 已退役(git 历史可考) | - 迭代 38 收口为带红合并〔用户特批 2026-10-26〕:09 静态扫描 S13 gdstyle 恶化 2 条经批准记入基线存量红(git 提交 c4c69701),卡② 停卡退上游,处方已于 2026-10-26 修订定稿 v1.3(git 提交 b3ea7532),随「gdstyle 存量债全量清偿」条目波 7 待编排。 - 迭代 39 收口为带红合并〔用户特批 2026-10-27〕:02 EV 锚 goblin 0.9148∉[1.00,1.20](触发器批有意行为改动,fp f74b9a48ef4a)已随 EV 锚重锚批换带归绿(git 提交 ba5105aa);08d 生涯.md:55 行号漂移已随 2026-10-28 批后收尾反哺落文修复归绿。三卡拆分后终局 gdstyle 恶化 2 条(battle_orchestrator max-file-length、level_map_screen max-class-variables)归迭代 40 卡①还债与迭代 41 存量债序列。 diff --git a/tools/ci_check.sh b/tools/ci_check.sh index 5ec916a7..28ded23c 100755 --- a/tools/ci_check.sh +++ b/tools/ci_check.sh @@ -1,11 +1,12 @@ #!/usr/bin/env bash # CI 现查件——按需读远端 run 的终局态,只呈报、不落盘(2026-11-04 用户裁:回执等待件与本地缓存判定退役)。 # 用法: tools/ci_check.sh [<提交hash>](缺省=当前 HEAD) -# 判据:Gitea commit status 只用来取本次任务的 run 链接,绿红一律认 run 自身的 status/conclusion—— -# run 未 completed(排队/在跑/尝试级中间态)与零触发批(纯闸件/管线批不建任务)一律呈报「未落定」,不写红。 +# 判据:Gitea commit status 只用来取本次任务的 run 链接,绿红一律认 run 自身的 status/conclusion, +# 且绿必须坐实「跑闸步真跑过」——零触发批的 run 照样建、照样 success,但跑闸步是 skipped, +# 一条闸都没跑,读成绿就是假绿(2026-11-04 run 55 实证)。run 未 completed(排队/在跑/尝试级中间态)呈报未落定。 # 调用面:开工前读态(红未修不开新批)、合回后想知道结果时手动查——合回流程不等待、不唤醒,呈报即回合止。 # 授权:GITEA_TOKEN 环境变量优先,否则读 git 凭据库(host=git.kuaimeo.com)。 -# 退出码: 0=绿 1=红 2=未落定/零触发/查不到 3=参数或令牌错误 +# 退出码: 0=绿(跑闸步真跑过) 1=红 2=未落定/不可判/查不到 3=参数或令牌错误 4=未验(零触发批,跑闸步全跳过) set -u COMMON="$(git -C "$(dirname "$0")" rev-parse --path-format=absolute --git-common-dir 2>/dev/null)" \ || { echo "不在 git 仓库内"; exit 3; } @@ -49,6 +50,11 @@ def undetermined(msg): sys.exit(2) +def unknown(msg): + print("CI现查: 不可判 | commit %s | %s" % (short(base), msg)) + sys.exit(2) + + try: s = get(api + "/commits/%s/status" % base) except urllib.error.HTTPError as e: @@ -59,7 +65,7 @@ except Exception as e: statuses = s.get("statuses") or [] target = next((x.get("target_url", "") for x in statuses if x.get("target_url")), "") if not statuses: - undetermined("远端无该提交的任务——零触发批(纯闸件/管线批不建任务),或推送未触发 CI") + undetermined("远端无该提交的 status——该批没推上去(或推的不是 master);零触发批有 run,走 run 侧读数") m = re.search(r"/actions/runs/(\d+)", target or "") if not m: @@ -75,20 +81,32 @@ rstatus, rconclusion = run.get("status"), run.get("conclusion") if rstatus != "completed": undetermined("run %s status=%s(runner 需开机在线;队列与日志见 %s/actions)" % (run_id, rstatus, web)) +try: + jobs = get(api + "/actions/runs/%s/jobs" % run_id).get("jobs", []) or [] +except Exception as e: + unknown("查 run %s 的 job 明细失败:%s——取不到步级读数就不下绿" % (run_id, e)) + +gate_steps = [x.get("conclusion") for j in jobs for x in (j.get("steps") or []) if "跑闸" in (x.get("name") or "")] + if rconclusion == "success": - print("CI现查: 绿 | commit %s | run %s conclusion=success" % (short(base), run_id)) + if not jobs: + unknown("run %s conclusion=success 但 job 列表为空,无法确认闸是否真跑" % run_id) + if not gate_steps: + unknown("run %s 里没有「跑闸」步——工作流结构已改,本件的步级判据需随动(查 %s/actions/runs/%s)" % (run_id, web, run_id)) + if all(c == "skipped" for c in gate_steps): + print("CI现查: 未验 | commit %s | run %s conclusion=success 但跑闸步全为 skipped——零触发批,远端一条闸都没跑" % (short(base), run_id)) + sys.exit(4) + print("CI现查: 绿 | commit %s | run %s conclusion=success,跑闸步 %d 条真跑过(闸况明细查 job 日志)" % (short(base), run_id, len(gate_steps))) sys.exit(0) red_jobs = [] -try: - jobs = get(api + "/actions/runs/%s/jobs" % run_id) - for j in jobs.get("jobs", []): - if j.get("conclusion") in ("success", "skipped", None): - continue - bad_steps = [x.get("name") for x in (j.get("steps") or []) if x.get("conclusion") not in ("success", "skipped")] - red_jobs.append((j.get("name"), bad_steps)) -except Exception as e: - red_jobs.append(("" % e, [])) +for j in jobs: + if j.get("conclusion") in ("success", "skipped", None): + continue + bad_steps = [x.get("name") for x in (j.get("steps") or []) if x.get("conclusion") not in ("success", "skipped")] + red_jobs.append((j.get("name"), bad_steps)) +if not red_jobs: + red_jobs.append(("" % rconclusion, [])) print("CI现查: 红 | commit %s | run %s conclusion=%s" % (short(base), run_id, rconclusion)) for name, steps in red_jobs: diff --git a/tools/gdstyle.toml b/tools/gdstyle.toml index 4f097cd7..d4466b5a 100644 --- a/tools/gdstyle.toml +++ b/tools/gdstyle.toml @@ -6,7 +6,7 @@ # INT64_MIN 负字面量是已知误报(Godot 自家解析器放行);type-hint 与 S9 类型闸重叠关; # empty-function 关(合法桩形态自由)。quality/no-debug-print 本是 opt-in 默认不跑,此处显式开 # ——产品码残留 print() 属真缺陷。阈值(函数长度/参数数等)取 gdstyle 默认值: -# 改阈值=基线口径变,须随批人工重生成基线。工具版本钉 v0.4.0(闸件校验,升级须重测兼容性)。 +# 改阈值=基线口径变,须随批人工修订基线(手动编辑 gdstyle_baseline.txt,经用户批准)。工具版本钉 v0.4.0(闸件校验,升级须重测兼容性)。 [rules] # ── 格式类全关(与 S9 类型闸/S10 文件头闸职能重叠)── diff --git a/tools/gdstyle_baseline.txt b/tools/gdstyle_baseline.txt index d1d6b45e..13b21725 100644 --- a/tools/gdstyle_baseline.txt +++ b/tools/gdstyle_baseline.txt @@ -3,11 +3,10 @@ # (class variables/public methods/file length)=文件|规则;无数字条目=文件|规则|消息全文(裸键)。 # 带数条目行格式「键 = 数值」,数值=消息剥掉 (max N) 段后首个整数;无数字条目裸键。 # 判定=键不在基线红(NEW)、同键数值较登记值恶化红(WORSENED)、改小/持平不红。 -# 重生成=人工专用:python tools/gdstyle_gate.py --refresh(禁清基线换绿;改规则口径/工具升级须随批 -# 重生成;新键数较旧基线少逾 10% 须加 --force 显式确认)。 +# 基线增删改=人工手动编辑本文件(闸件无重写基线入口;禁清基线换绿;登记值只准因还债下降, +# 禁抬高到现状;改规则口径/工具升级须随批人工修订并经用户批准)。 game/core/adventure_runner.gd|quality/max-class-variables = 23 game/core/level_runner.gd|quality/max-class-variables = 30 game/core/level_runner.gd|quality/max-public-methods = 33 -game/core/minesweeper_rules.gd|quality/max-public-methods = 21 game/presentation/views/board_view.gd|quality/max-class-variables = 31 game/presentation/views/board_view.gd|quality/max-public-methods = 27 diff --git a/tools/gdstyle_gate.py b/tools/gdstyle_gate.py index 49c375a5..9dffee18 100644 --- a/tools/gdstyle_gate.py +++ b/tools/gdstyle_gate.py @@ -22,19 +22,15 @@ quality/*+syntax/reserved-identifier,format/naming/order 全关)。扫描 阈值口径=gdstyle 默认值(tools/gdstyle.toml 不设数值阈值);基线只是欠账簿,登记值只准因 还债下降,禁抬高到现状(抬高=把既有代码当尺子,默认恶化)。 -基线重生成=人工专用(--refresh,附新旧对账、骤降守卫与抬升守卫),禁在闸内自动重生成 -(防清基线换绿);新键数较旧基线少逾 10% 拒绝写入(防扫面断裂静默缩基线换绿);任一键登记 -值被抬高同样拒绝(防以现状为尺吞掉恶化)。两条守卫都须 --force 显式确认,--force 只在 -refresh 路径有效。 +基线维护=人工手动编辑基线文件(本闸无任何重写基线的入口——防清基线换绿;增删行与改登记值 +都是人工动作,须用户批准;登记值只准因还债下降,禁抬高到现状)。 二进制:本机固定路径 D:/code/gdstyle/gdstyle.exe(不入库不入包),GDSTYLE_BIN 环境变量覆盖; -版本与钉定版不符即红——升级工具须重测语法兼容性并人工重生成基线。 +版本与钉定版不符即红——升级工具须重测语法兼容性并人工修订基线。 退出码:0=无基线外新违规且无恶化;1=有新违规/有恶化/二进制缺失或版本不符/扫描面为空/ -输出不可解析/refresh 骤降或抬升拒写;2=用法错。 +输出不可解析;2=用法错。 用法:python tools/gdstyle_gate.py # 闸判定 - python tools/gdstyle_gate.py --refresh # 人工重生成基线(覆盖旧文件,附对账) - python tools/gdstyle_gate.py --refresh --force # 骤降/抬升守卫触发时显式确认写入 """ import json import os @@ -53,8 +49,6 @@ PINNED_VERSION = "0.4.0" DEFAULT_BIN = ("D:/code/gdstyle/gdstyle.exe" if sys.platform == "win32" else "/usr/local/bin/gdstyle") MAX_REPORT = 50 -MAX_VANISHED_REPORT = 20 -SHRINK_GUARD = 0.9 # 新键数 < 旧键数 * 本系数=骤降,refresh 拒写须 --force _FUNC_RE = re.compile(r"function '([^']+)'") _MAX_RE = re.compile(r"\s*\(max \d+\)") @@ -112,31 +106,13 @@ def parse_baseline() -> dict: return entries -def write_baseline(entries: dict) -> None: - lines = [ - "# gdstyle 存量基线(S13)——键每行一条;只记基线不记豁免理由。", - "# 键形态(稳定身份键,计数漂移不换键):函数级带数条目=文件|规则|函数名;类级/文件级带数条目", - "# (class variables/public methods/file length)=文件|规则;无数字条目=文件|规则|消息全文(裸键)。", - "# 带数条目行格式「键 = 数值」,数值=消息剥掉 (max N) 段后首个整数;无数字条目裸键。", - "# 判定=键不在基线红(NEW)、同键数值较登记值恶化红(WORSENED)、改小/持平不红。", - "# 重生成=人工专用:python tools/gdstyle_gate.py --refresh(禁清基线换绿;改规则口径/工具升级须随批", - "# 重生成;新键数较旧基线少逾 10% 须加 --force 显式确认)。", - ] - for key in sorted(entries): - value = entries[key] - lines.append("%s = %d" % (key, value) if value is not None else key) - BASELINE.write_text("\n".join(lines) + "\n", encoding="utf-8") - - def run_gate() -> int: if hasattr(sys.stdout, "reconfigure"): sys.stdout.reconfigure(encoding="utf-8", errors="replace") args = sys.argv[1:] - refresh = "--refresh" in args - force = "--force" in args - if (force and not refresh) or any(a not in ("--refresh", "--force") for a in args): - print("[gdstyle_gate] 用法: python tools/gdstyle_gate.py [--refresh] [--force](--force 只在 refresh 路径有效)") + if args: + print("[gdstyle_gate] 用法: python tools/gdstyle_gate.py(无参数;基线维护=人工手动编辑基线文件)") return 2 binary = os.environ.get("GDSTYLE_BIN", DEFAULT_BIN) @@ -167,39 +143,9 @@ def run_gate() -> int: current = collect_entries(findings) - if refresh: - old = parse_baseline() if BASELINE.exists() else None - if old is not None: - vanished = sorted(set(old) - set(current)) - print("[gdstyle_gate] 对账:旧基线 %d 条,新扫描 %d 条,消失键 %d 条" - % (len(old), len(current), len(vanished))) - for k in vanished[:MAX_VANISHED_REPORT]: - print(" GONE " + k) - if len(vanished) > MAX_VANISHED_REPORT: - print(" ...(截断,共 %d 条)" % len(vanished)) - if len(current) < len(old) * SHRINK_GUARD and not force: - return fail("新键数 %d 较旧基线 %d 少逾 10%%——疑扫面断裂静默缩基线换绿,拒绝写入;" - "确认缩基线正当(如删规则/缩扫描面)须加 --force 显式确认" % (len(current), len(old))) - raised = sorted( - (k, old[k], current[k]) for k in current - if k in old and old[k] is not None and current[k] is not None and current[k] > old[k] - ) - if raised and not force: - for k, was, now in raised[:MAX_REPORT]: - print(" FAIL 抬高 %s = %d(登记 %d)" % (k, now, was)) - if len(raised) > MAX_REPORT: - print(" ...(截断,共 %d 条)" % len(raised)) - return fail("重生成会抬高 %d 条登记值——基线只准因还债下降,抬高=以现状为尺默认恶化;" - "确属阈值口径变更或经用户批准须加 --force 显式确认" % len(raised)) - else: - print("[gdstyle_gate] 旧基线不存在,跳过对账(首次落位)") - write_baseline(current) - print("[gdstyle_gate] 基线已重生成:%s 条(%s)" % (len(current), BASELINE.name)) - return 0 - base = parse_baseline() if BASELINE.exists() else {} if not base and not BASELINE.exists(): - return fail("基线文件不存在:%s(首次落位跑 python tools/gdstyle_gate.py --refresh,须经用户批准)" % BASELINE.name) + return fail("基线文件不存在:%s(首次落位=人工创建基线文件、格式见文件头注,须经用户批准)" % BASELINE.name) new = sorted(k for k in current if k not in base) worsened = sorted( @@ -222,7 +168,7 @@ def run_gate() -> int: print(" FAIL ...(截断,共 %d 条)" % len(worsened)) red = True if red: - return fail("基线外新违规 %d 条/恶化 %d 条——新码须修到基线口径内,恶化须还债或经用户批准随批重生成基线" + return fail("基线外新违规 %d 条/恶化 %d 条——新码须修到基线口径内,恶化须还债或经用户批准随批人工修订基线" % (len(new), len(worsened))) print("[gdstyle_gate] ok") return 0 diff --git a/待办清单.md b/待办清单.md index 3b0fbd45..5c91e57d 100644 --- a/待办清单.md +++ b/待办清单.md @@ -2,22 +2,6 @@ 本清单是流水线的唯一登记处:以后才做的事在此登记一条,随流水线段推进改状态,做完整条删除(条目记进度,不是各段的开工前置);各系统文档的「待办」节只留一行指路存根,不再自建条目。条目格式(标题=登记元数据含可选优先级,正文=实况/缺口/改动面/状态四属性)与状态机以 [doc-conventions §12.1](design/engineering/doc-conventions.md) 为权威。 -#### L1 深度 3 改地精+熊地精混编(大地精数据行退役)(2026-11-04 登记,来源=会话提及) - -**实况**:关联文档清单——[敌人系统](design/gdd/systems/战斗循环/敌人系统.md) v1.7(hobgoblin 缺口登记整块删除;敌种名录表已随工程批退役,行数据逐行读表)· [难度曲线与Boss](design/gdd/systems/冒险循环/难度曲线与Boss.md) v1.3(混编投放记录与 Alpha 读数义务口径)· [08-Alpha版本标准](design/gdd/08-Alpha版本标准.md) v1.26(混编遭遇行集状态行补第二行)· [流程规范](design/engineering/process-conventions.md) §3 第 5 条(Alpha 阶段零读数口径,2026-11-04 用户裁)· [体验验证清单](体验验证清单.md) ⑱(目检范围扩至 L1 节点 3)· 需求卡片 [需求卡片-L1深度3混编](reports/需求卡片-L1深度3混编-2026-11-04.md)(2026-11-04 写卡,八条验收断言 R1–R8、零待裁点)。事项来由与设计定值:用户 2026-11-04 裁不做大地精敌种,原「hobgoblin 内容三件套补齐」条目同批删除;(1, battle, 3) 改双行混编,行值整行复用 (1, battle, 2) 熊地精(1 只 / hp22 / ac2)与 (1, battle, 0) 地精(1–2 只 / hp8 / ac0),行序熊地精在前(默认单体目标与开战叙述取首行),静态最坏骰和 1+2=3,Alpha 阶段零读数。 - -**改动面**:文档+游戏代码+工具代码 - -**状态**:文档设计已闭合+已写卡+已编迭代 51 - -#### 架构审查余项——闸面缺口、豁免存废、零测试点名与架构文档漂移(2026-11-03 登记,来源=批次移交) - -**实况**:2026-10-29 全库架构审计(reports/审计-全库架构审查-2026-10-29.md)的待裁余项,自同名讨论条目迁入。现行:①闸面缺口(适用域落 code-conventions §4 第 13 条)②S13 豁免清偿(commit 9eedf896)③零测试点名(承接面落 test-conventions §8.3)三组随 §4 批落地(2026-11-03 用户裁决,CI 66407117 green);④架构文档漂移随 arch51-docs 批合回;§5.1 卡=reports/需求卡片-架构审查5.1封装修复批-2026-11-03.md v1.1(2.875 工作日);§5.3 卡=reports/需求卡片-架构审查P2代码面批-2026-11-03.md v1.1(0.25 工作日);EC8 热重载经用户裁撤卡(实装去向=另立条目);presentation 层私取面 2026-11-04 设计闭合并写卡(443 行/14 文件;用户两裁=三内部数据类字段公开化+四族一批)=reports/需求卡片-架构审查presentation层封装修复批-2026-11-04.md v1.0(4.125 工作日,凭据=reports/处置-presentation层封装修复-2026-11-04.md)。 - -**改动面**:文档+游戏代码+工具代码 - -**状态**:文档设计已闭合+已写卡+已编迭代 51 - #### 三关色相 × 五组微光互辨抽测——三关图类型色板终值冻结的前置抽测(2026-10-28 登记,来源=会话提及) **实况**:三关图类型色板(`tile_closed` 与 `wall_ambient` 两槽)终值冻结前须先跑「三关色相 × 五组类型微光」互辨抽测(格底与类型微光同在未开格面,邻近色相有吞没风险);美术设计段已闭合——取样面 54 格(3 关 × 5 组 × 3 底型+9 基准格)、判据=目检四条+机检四条(阈值全取在役值,色相通道不设机检阈值)、产物=并列样图+逐对读数表两兼。执行步骤与三件定值全载抽测方案过程稿 reports/提案-三关色相互辨抽测方案-2026-10-29.md;抽测挂点=[美术圣经](design/art/art-bible.md) v3.22 §6.3 终值取值程序第一条(终值冻结闸=§1.4 格子样张重跑)。执行前提已核:三关瓦片三套在本机 `game/assets/art/board/` 齐备,可开跑。 @@ -261,16 +245,6 @@ ### 文档与结构 -#### EffectPort biz_fact 键 charge_layers——无属主数据游离出领域实体的处置(2026-11-02 登记,来源=审计发现) - -**实况**:证据=reports/审计-全库架构审查-2026-10-29.md §3.1 B 类第 2 行+`game/core/effect_port.gd:4`(biz_fact 闭面五键)+`game/core/action_economy.gd:14/37/203`(裸账本与唯一写点)。2026-11-02 架构审查逐键核闭面:其余四键各有领域实体持有数据,唯 charge_layers 背后是无主账本(全仓零订阅注册、零表行消费);用户裁决=删除方向,总判据「机制数据一律长在所属封装实体的内部属性(表行字段)里,全局常量与无主账本清零」。需求卡片 reports/需求卡片-EffectPort蓄力层删键批-2026-11-04.md(v1.1——处置范围、残留面 15 处考证、断言换代申报与 grilling 四裁点落稿全载卡内)。 - -**2026-11-04 grilling 四裁(实现面按推荐案)**:①注释只清 charge_layers 关联语义(四处去退役名留机制描述),五拍其余退役名不动;②改写族孤儿另立条目(见下);③req-card 落「卡片落盘时点」条款;④编排凑批。纠错记录:v1.0 曾成文未复核态被误收口合回(错误在案);v1.1 新 worktree 落笔、成立裁决后才合回。 - -**改动面**:游戏代码 - -**状态**:已写卡+已编迭代 51 - #### damage_controller 按序改写族——内容孤儿机制与退役名注释层(2026-11-04 登记,来源=会话提及) **实况**:damage_controller.gd 按序改写族通用机制(trade_hit/trade_atk 交换、armor_rewrite 免掷、spike 满层必中与倍乘、discount_shift 轻甲改善——注释叙事 :266-273、改写执行 :283-309、spike 倍乘 :350-353)现役内容面仅淬毒刃纹一行 modify_ticket(mode=clamp_bonus,feats.tres:854):其余子分支零表行注册(全仓 grep 证,含天赋树 tree_rules 面零 spike)——「框架先行、内容未接」同族债,与 charge_layers 同形态但不持数据键。五拍注释全部以旧 27 专长名叙事(矿工重锤/专注/厚积薄发/猎弱本能,道具退役素材库.md:43-47 退役在案);其中 charge_layers 关联四处已归 EffectPort 蓄力层删键批卡处理,其余退役名注释不在该卡范围。证据:reports/需求卡片-EffectPort蓄力层删键批-2026-11-04.md 范围边界节(2026-11-04 grilling 复核发现)。 @@ -280,3 +254,27 @@ **改动面**:游戏代码 **状态**:待文档设计 + +#### minesweeper_rules 公开面还债——S13 超标键撤销后的清偿(2026-11-04 登记,来源=批次移交,优先级=P0) + +**实况**:证据=tools/gdstyle_baseline.txt(本批撤销无凭证键后,gdstyle 闸红单键:game/core/minesweeper_rules.gd 公开方法 21>上限 20);+2 搬家方法 harmful_variants/harmful_adjacent 为迭代51卡② R2「五方法归位」裁决的直接后果(git 提交 7f512aa8),基点漂移考证:写卡基点 6261b36e 实数 18,iter50-卡3 a2886a53 +1 → 实现基点 19,+2=21。还债方向:settle_batch/fx_reveal 族收敛或搬迁,公开方法 21→≤20;还债批合回后 gdstyle 归绿(CI 追绿),期间代码域 CI 红在案、文档批不受影响(域分流)。 + +**改动面**:游戏代码 + +**状态**:待写卡 + +#### EffectEngine 死函数与全仓孤儿函数清退(2026-11-04 登记,来源=会话提及,优先级=P0) + +**实况**:证据=game/core/effect_engine.gd:204 has_effect_on 全仓零调用方(迭代51卡①删唯一调用方后成死码,grep 仅定义命中;卡① 备案见 git 提交 7f512aa8;2026-11-04 用户裁=删并全仓排查)。范围=删除 has_effect_on+全仓排查生产码零调用死函数/孤儿函数一并清退;测试直连与受控例外面不算死码,排查随写卡段考证。 + +**改动面**:游戏代码 + +**状态**:待写卡 + +#### 架构审查 presentation 层封装修复——已写卡待编迭代(2026-11-04 登记,来源=批次移交) + +**实况**:需求卡片 reports/需求卡片-架构审查presentation层封装修复批-2026-11-04.md v1.1(4.125 工作日;grilling 六项复核折入=git 提交 5fc9a131;用户两裁=三内部数据类字段公开化+四族一批;凭据=reports/处置-presentation层封装修复-2026-11-04.md)。443 行/14 文件四族(A1 数据类/A2 拆件子件/B 组合根成对转发梯/C 杂项)。自「架构审查余项」条目迁出(该条随迭代51完成整条删除,本卡未编迭代 51,由此条承接)。 + +**改动面**:游戏代码 + +**状态**:文档设计已闭合+已写卡