From a69310b73862aca9f6cf94a3e0a45fdd0a86b666 Mon Sep 17 00:00:00 2001 From: DKChan <524912269@qq.com> Date: Mon, 9 Nov 2026 08:22:04 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=86=85=E5=AE=B9=E9=94=9A=E6=94=B9?= =?UTF-8?q?=E7=89=88=E6=89=B9(=E5=88=A4=E6=8D=AE=E9=94=9A=E8=A1=8C?= =?UTF-8?q?=E5=8F=B7=E5=BD=A2=E6=80=81=E5=BA=9F=E6=AD=A2):=20=E9=94=9A?= =?UTF-8?q?=E5=BD=A2=E6=80=81=E5=94=AF=E4=B8=80=E5=8C=96<=E8=B7=AF?= =?UTF-8?q?=E5=BE=84>=E3=80=8C=E8=8A=82=E5=90=8D=E3=80=8D<=E8=A1=8C?= =?UTF-8?q?=E5=85=B3=E9=94=AE=E8=AF=8D>=E2=80=94=E2=80=94=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E8=A3=81:=20=E9=94=9A=E6=8C=87=E5=90=91=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E4=B8=8D=E6=8C=87=E5=90=91=E8=A1=8C=E5=8F=B7,?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E5=A2=9E=E5=88=A0=E8=A1=8C=E4=B8=8D=E7=89=B5?= =?UTF-8?q?=E5=8A=A8=E9=94=9A=E4=B8=8E=E6=B5=8B=E8=AF=95=E4=BB=A3=E7=A0=81?= =?UTF-8?q?,=E5=88=A4=E6=8D=AE=E5=8F=A5=E5=86=85=E5=AE=B9=E7=9C=9F?= =?UTF-8?q?=E6=94=B9=E5=8A=A8=E6=89=8D=E5=A4=B1=E9=85=8D(=E5=A4=B1?= =?UTF-8?q?=E9=85=8D=3D=E7=BA=A2,=E6=94=B9=E5=8F=A5=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E6=89=B9=E5=90=8C=E6=89=B9=E6=94=B9=E9=94=9A)=E3=80=82?= =?UTF-8?q?=E8=A7=84=E7=BA=A6=E8=90=BD=E6=96=87:=20test-conventions=20?= =?UTF-8?q?=C2=A78.3=20=E5=88=A4=E6=8D=AE=E5=87=BA=E5=A4=84=E9=94=9A?= =?UTF-8?q?=E4=B8=A4=E6=9D=A1=E6=96=87(=E5=8D=A1=E7=89=87=E9=94=9A/?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=87=BD=E6=95=B0=E6=B3=A8=E8=AE=B0)+=C2=A78?= =?UTF-8?q?.2=20golden=20=E9=A2=84=E8=A7=88=E5=8F=A5+=C2=A78.10=20?= =?UTF-8?q?=E5=AE=A1=E8=AE=A1=E6=A0=B8=E5=AF=B9=E5=8F=A5+req-card=20=C2=A7?= =?UTF-8?q?8=20=E9=94=9A=E8=A7=84=E6=A0=BC/=E5=A4=8D=E6=A0=B8=E9=97=A8?= =?UTF-8?q?=E5=AE=9E=E8=AF=BB/description+iter=20=E5=BC=80=E5=B7=A5?= =?UTF-8?q?=E9=97=A8+iter-plan=20=E9=A2=84=E6=A3=80=E7=AC=AC3=E6=AD=A5+pro?= =?UTF-8?q?cess-conventions=20=E5=86=99=E5=8D=A1=E6=AE=B5=E8=A1=8C;=20?= =?UTF-8?q?=E9=97=B8=E4=BB=B6:=20pipeline=5Fgate=20C5=20=E4=B8=8E=20capabi?= =?UTF-8?q?lity=5Faudit=20=E6=B3=A8=E8=AE=B0=E9=81=93=E6=94=B9=E6=A0=B8?= =?UTF-8?q?=E3=80=8C=E8=8A=82=E5=90=8D=E5=9C=A8=E6=A1=A3+=E5=85=B3?= =?UTF-8?q?=E9=94=AE=E8=AF=8D=E5=91=BD=E4=B8=AD=E8=8A=82=E5=86=85=E3=80=8D?= =?UTF-8?q?(=E5=85=B1=E7=94=A8=E4=BB=B6=20tools/anchor=5Futil.py=20?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E5=8D=95=E7=82=B9:=20=E5=90=8C=E5=90=8D?= =?UTF-8?q?=E8=8A=82=E7=B2=BE=E7=A1=AE=E5=91=BD=E4=B8=AD=E4=BC=98=E5=85=88?= =?UTF-8?q?=E3=80=81=E5=9B=B4=E6=A0=8F=E5=86=85#=E4=B8=8D=E4=BD=9C?= =?UTF-8?q?=E8=8A=82=E7=95=8C=E3=80=81.gd=20=E6=B5=8B=E9=87=8F=E9=9D=A2?= =?UTF-8?q?=E6=8C=89=E6=96=87=E4=BB=B6=E5=86=85=E5=AD=90=E4=B8=B2),?= =?UTF-8?q?=E8=A1=8C=E5=8F=B7=E5=BD=A2=E6=80=81=E5=87=BA=E7=8E=B0=E5=8D=B3?= =?UTF-8?q?=E7=BA=A2;=20=E5=AD=98=E9=87=8F=E8=BF=81=E7=A7=BB:=20=E6=B5=8B?= =?UTF-8?q?=E8=AF=95/=E6=8E=A2=E9=92=88=E6=B3=A8=E8=AE=B0=20604=20?= =?UTF-8?q?=E6=9D=A1=E5=85=A8=E9=87=8F=E5=86=85=E5=AE=B9=E5=8C=96(?= =?UTF-8?q?=E8=A1=8C=E5=8F=B7=E5=BD=A2=E6=80=81=20568+=E5=AD=98=E9=87=8F?= =?UTF-8?q?=E6=AE=8B=E5=BD=A2=2036=20=E9=87=8D=E9=94=9A)+=E5=9C=A8?= =?UTF-8?q?=E7=9B=98=E4=BA=94=E5=8D=A1=20md=20=E8=A1=8C=E5=8F=B7=E6=8C=87?= =?UTF-8?q?=E9=92=88=2074=20=E5=A4=84=E5=86=85=E5=AE=B9=E5=8C=96+=E5=86=99?= =?UTF-8?q?=E5=8D=A1=E6=AE=B5=E5=AD=98=E9=87=8F=E5=8D=8A=E6=88=90=E5=93=81?= =?UTF-8?q?=E9=94=9A=E4=BF=AE=E6=AD=A3(=E5=8F=8D=E5=BC=95=E5=8F=B7?= =?UTF-8?q?=E5=90=9E=E8=AF=8D=E5=B0=BE=2012=20=E5=A4=84=E3=80=81=E6=9D=82?= =?UTF-8?q?=E5=B0=BE=202=20=E5=A4=84=E3=80=81=E8=BF=87=E6=9C=9F=E8=AF=8D?= =?UTF-8?q?=E9=87=8D=E9=94=9A=202=20=E5=A4=84);=20=E7=99=BB=E8=AE=B0?= =?UTF-8?q?=E6=9D=A1=E7=9B=AE=E6=8C=89=E6=96=B0=E8=A3=81=E5=86=B3=E6=94=B9?= =?UTF-8?q?=E5=86=99(=E5=BE=85=E6=89=A7=E8=A1=8C)=E3=80=82=E5=8C=BA?= =?UTF-8?q?=E5=86=85=E5=87=AD=E6=8D=AE:=20=E6=B5=81=E6=B0=B4=E7=BA=BF?= =?UTF-8?q?=E9=97=B8=20PASS(36=20=E6=9D=A1=E7=9B=AE/57=20=E8=A1=8C/5=20?= =?UTF-8?q?=E5=8D=A1=E5=85=A8=E8=BF=87)+=E8=83=BD=E5=8A=9B=E5=AE=A1?= =?UTF-8?q?=E8=AE=A1=20--strict=20455=20=E6=B3=A8=E8=AE=B0=E5=87=BD?= =?UTF-8?q?=E6=95=B0=200=20=E7=BA=A2+=E6=96=87=E6=A1=A3=E5=9F=9F=E9=97=B8?= =?UTF-8?q?=E3=80=90=E9=AA=8C=E6=94=B6=E9=80=9A=E8=BF=87=E3=80=91=E6=97=A0?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=BA=A2;=20=E8=BF=81=E7=A7=BB=E4=BB=B6?= =?UTF-8?q?=E4=B8=80=E6=AC=A1=E6=80=A7=E7=94=A8=E5=90=8E=E5=8D=B3=E5=88=A0?= =?UTF-8?q?=E6=9C=AA=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .zcode/skills/iter-plan/SKILL.md | 2 +- .zcode/skills/iter/SKILL.md | 2 +- .zcode/skills/req-card/SKILL.md | 6 +- design/engineering/process-conventions.md | 2 +- design/engineering/test-conventions.md | 8 +- game/probe/board_shot_probe.gd | 6 +- game/probe/fx_probe.gd | 2 +- game/probe/fx_shot_probe.gd | 6 +- game/probe/layout_probe.gd | 4 +- game/probe/level_map_shot_probe.gd | 6 +- game/probe/level_map_viewport_probe.gd | 22 ++--- game/probe/probe_coverage_recorder.gd | 2 +- game/probe/screen_flow_probe.gd | 26 +++--- game/probe/shot_probe.gd | 32 +++---- game/probe/t17_defer_probe.gd | 2 +- game/probe/type_glow_shot_probe.gd | 2 +- game/probe/ui_click_probe.gd | 52 +++++------ game/probe/ui_contrast_probe.gd | 2 +- game/probe/ui_input_probe.gd | 26 +++--- game/probe/ui_probe.gd | 28 +++--- game/probe/ui_tune_probe.gd | 12 +-- game/tests/smoke_boot.gd | 6 +- game/tests/system_test.gd | 16 ++-- .../unit/battle_settlement/boss_gate_test.gd | 4 +- .../damage_controller_test.gd | 26 +++--- .../battle_settlement/damage_math_test.gd | 10 +- .../battle_settlement/effect_port_test.gd | 8 +- .../extended_row_violation_test.gd | 2 +- .../battle_settlement/refresh_feats_test.gd | 26 +++--- .../reward_ineffective_reason_test.gd | 6 +- .../battle_settlement/roll_multiplier_test.gd | 14 +-- .../round_flow_skill_pool_test.gd | 32 +++---- .../battle_settlement/seal_polarity_test.gd | 40 ++++---- .../settlement_wiring_snapshot_test.gd | 4 +- .../battle_settlement/skill_unlock_test.gd | 10 +- .../battle_settlement/trigger_cond_test.gd | 2 +- .../variant_placement_test.gd | 10 +- .../tests/unit/contracts/source_guard_test.gd | 4 +- .../unit/contracts/system_contracts_test.gd | 50 +++++----- game/tests/unit/core/adventure_feats_test.gd | 10 +- .../unit/core/auto_player_deduce_test.gd | 2 +- .../unit/core/battle_driver_drive_test.gd | 8 +- game/tests/unit/core/board_gen_reward_test.gd | 10 +- game/tests/unit/core/board_generator_test.gd | 14 +-- .../tests/unit/core/breakpoint_resume_test.gd | 2 +- .../core/config_db_cross_validator_test.gd | 8 +- .../unit/core/config_db_resolver_test.gd | 14 +-- .../unit/core/curio_refresh_paid_test.gd | 2 +- game/tests/unit/core/effect_words_t1_test.gd | 2 +- .../unit/core/encapsulation_p2_sweep_test.gd | 12 +-- .../unit/core/encapsulation_sweep_test.gd | 20 ++-- game/tests/unit/core/feat_vouchers_test.gd | 2 +- game/tests/unit/core/hero_ledger_test.gd | 2 +- .../unit/core/level_map_type_vis_test.gd | 18 ++-- .../unit/core/level_shop_economy_test.gd | 28 +++--- .../unit/core/level_table_validate_test.gd | 8 +- .../unit/core/meta_progression_forge_test.gd | 30 +++--- .../tests/unit/core/minesweeper_rules_test.gd | 22 ++--- .../unit/core/node_map_generator_test.gd | 22 ++--- game/tests/unit/core/node_map_growth_test.gd | 10 +- .../unit/core/playtest_logger_guard_test.gd | 2 +- game/tests/unit/core/pool_case_d_test.gd | 10 +- game/tests/unit/core/run_time_fatal_test.gd | 12 +-- .../unit/core/save_boot_no_activate_test.gd | 8 +- .../unit/core/save_manager_domain_test.gd | 6 +- .../unit/core/save_slot_isolation_test.gd | 6 +- .../tests/unit/core/save_slot_summary_test.gd | 6 +- game/tests/unit/core/settle_segments_test.gd | 2 +- game/tests/unit/core/treasure_effects_test.gd | 4 +- game/tests/unit/core/treasure_items_test.gd | 2 +- .../unit/core/tree_requires_level_test.gd | 2 +- game/tests/unit/core/tree_rules_v11_test.gd | 4 +- game/tests/unit/cross_system_flow_test.gd | 10 +- .../data_config/config_db_fatal_oob_test.gd | 4 +- game/tests/unit/data_config/config_db_test.gd | 14 +-- .../data_config/counter_prefix_fatal_test.gd | 4 +- .../data_config/effect_kind_retired_test.gd | 4 +- game/tests/unit/data_config/elite_row_test.gd | 12 +-- .../unit/data_config/forge_table_test.gd | 10 +- .../unit/data_config/level_gen_params_test.gd | 8 +- .../reward_dangling_treasure_test.gd | 4 +- .../unit/data_config/rng_service_test.gd | 10 +- .../unit/data_config/rng_stream_boot_test.gd | 2 +- .../data_config/table_structure_guard_test.gd | 32 +++---- .../treasure_target_violation_test.gd | 4 +- game/tests/unit/example_test.gd | 2 +- game/tests/unit/node_map_determinism_test.gd | 4 +- .../presentation/animation_frame_spec_test.gd | 6 +- .../presentation/battle_log_zero_text_test.gd | 8 +- .../unit/presentation/battle_narrator_test.gd | 14 +-- .../presentation/camp_scene_layout_test.gd | 8 +- .../unit/presentation/confirm_dialog_test.gd | 6 +- .../unit/presentation/forge_workbench_test.gd | 4 +- .../unit/presentation/hud_presenter_test.gd | 8 +- .../presentation/level_map_info_fog_test.gd | 16 ++-- .../unit/presentation/modal_flow_test.gd | 2 +- .../unit/presentation/pacing_queue_test.gd | 12 +-- .../palette_token_pairwise_test.gd | 4 +- .../presentation/player_copy_sweep_test.gd | 16 ++-- .../playtest_logger_step_fields_test.gd | 8 +- .../presentation_encapsulation_sweep_test.gd | 16 ++-- .../unit/presentation/reward_overlay_test.gd | 6 +- .../presentation/seal_mark_params_test.gd | 10 +- .../unit/presentation/settings_store_test.gd | 8 +- .../presentation/stage_background_test.gd | 22 ++--- .../presentation/standee_fx_sweep_test.gd | 2 +- .../standee_present_values_test.gd | 4 +- .../presentation/terrain_tile_sets_test.gd | 8 +- .../presentation/theme_projection_test.gd | 24 ++--- .../tune_sim_batch_parity_test.gd | 4 +- .../tests/unit/presentation/type_glow_test.gd | 12 +-- .../unit/presentation/ui_font_asset_test.gd | 2 +- game/tests/unit/save_rng_roundtrip_test.gd | 6 +- .../tests/unit/schema_vocab_violation_test.gd | 16 ++-- reports/需求卡片-刷新经济改版批-2026-11-09.md | 50 +++++----- reports/需求卡片-可推理率退役批-2026-11-09.md | 16 ++-- ...‚卡片-棋盘瓦片与立体表现重做批-2026-11-07.md | 40 ++++---- .../需求卡片-营地场景重排接线-2026-11-07.md | 22 ++--- reports/需求卡片-跨表量级护栏批-2026-11-09.md | 20 ++-- tools/anchor_util.py | 91 +++++++++++++++++++ tools/capability_audit.py | 48 ++++++---- tools/pipeline_gate.py | 46 ++++++---- 待办清单.md | 9 +- 123 files changed, 832 insertions(+), 716 deletions(-) create mode 100644 tools/anchor_util.py diff --git a/.zcode/skills/iter-plan/SKILL.md b/.zcode/skills/iter-plan/SKILL.md index 9bb431f6..b27a79c2 100644 --- a/.zcode/skills/iter-plan/SKILL.md +++ b/.zcode/skills/iter-plan/SKILL.md @@ -50,7 +50,7 @@ description: g-plan2(Dungeon Sweeper)五段流水线第四段的迭代编排 |---|---|---| | 1 | 卡内一致性互证 | 🔴契约 vs 任务卡 vs 验证闸对照表 vs 落位预检互相印证——汇总级抽查即可,逐条细查归写卡段复核(req-card grilling 门) | | 2 | 代码现状锚实核 | 卡片「现状事实」每条 file:line 打开实读;落位预检的新名 grep 全仓应零命中;「计划新增」件核不存在、「复用既有」件核存在 | -| 3 | 判据出处行锚实核 | 对照表每行锚所指文档行打开实读,核句子在位**且内容与该行判据匹配**——机检 C5 只查存在性,查不出内容错位;写卡后文档被其他批改动会使锚漂移(2026-11-07 退役卡 ux 四锚漂移实证) | +| 3 | 判据出处锚实核 | 对照表每行锚按索引(节名定位、行关键词命中行)打开文档节句实读,核句子在位**且内容与该行判据匹配**——机检 C5 核到「关键词命中节内」粒度、查不出语义错位,实读兜语义(2026-11-09 内容锚改版后行号漂移面已消,句内容真改动时关键词失配机检即红) | | 4 | 验收协议可执行性 | 对拍/等价/重放类判据的「改前基线+改后载体」两腿齐备:基线怎么来(采集步骤在卡内)、载体在盘可跑(工具在 tools/、锚在 sim-data/、golden 基线在 game/tests/golden/) | | 5 | 跨卡触碰面交集与卡序语义依赖 | 点名卡集两两过文件交集;同文件改动的语义序(前卡删除面 vs 后卡引用面);卡序与卡片内取用/产出声明一致 | | 6 | 跨批次断言钉死面 | 在飞或刚合回批次新增的断言(词表在册、表值钉、行为断言)是否钉住本批要改的退役面 | diff --git a/.zcode/skills/iter/SKILL.md b/.zcode/skills/iter/SKILL.md index 1d9cbe4f..b3a2b3c7 100644 --- a/.zcode/skills/iter/SKILL.md +++ b/.zcode/skills/iter/SKILL.md @@ -27,7 +27,7 @@ description: g-plan2 迭代开工总指挥。当用户输入 /iter <迭代号> - **待裁点 ≠ 0**:需求卡片声明待裁点未全裁,或行内有「待用户裁甲/乙」句。 - **迭代估时总量 <5 个工作日**:迭代行状态应处「冻结待凑批」——处待开工/进行中且总量不足即编排缺陷,拒启动并呈报凑批方案(可补卡清单)等用户裁(2026-10-25 两层模型:卡片无工作量门槛,冻结线属迭代层)。 - **需求卡片缺失**:行内引用的需求卡片文件不存在或版本明显滞后于行内裁决记录。 -- **改动—验收对照表缺失或不闭合(2026-10-11 立,2026-10-21 升级)**:需求卡片没有改动—验收对照表,或对照表有空行(无真实入口、无判据绑定面),或 T 卡内无对应验收条目 → 不过,停工呈报。**判定口径:每个需求点至少一行;每行必须有落点、真实入口、判据绑定面**——施工性质的验证工作(如「MC 对账适配」)、完成定义里的笼统验证手段(如「MC 对拍留证」)都不算。禁拿 AGENTS.md「新功能必配新测试」红线代偿——那条只保证写了测试,不保证测得对。2026-10-21 前的旧卡缺对照表 → 停工,退回写卡段补,补完再开工。**判据出处行锚(2026-11-05 起):生效日后(文件名日期不早于该日)的卡,对照表「需求点」格须带 `<现行文档相对路径>:<行号>` 判据出处行锚(机检=pipeline_gate C5)——行缺锚或锚指向不存在=停工呈报退写卡段;旧卡不回头改,开工前由写卡段补挂**(test-conventions §8.3)。 +- **改动—验收对照表缺失或不闭合(2026-10-11 立,2026-10-21 升级)**:需求卡片没有改动—验收对照表,或对照表有空行(无真实入口、无判据绑定面),或 T 卡内无对应验收条目 → 不过,停工呈报。**判定口径:每个需求点至少一行;每行必须有落点、真实入口、判据绑定面**——施工性质的验证工作(如「MC 对账适配」)、完成定义里的笼统验证手段(如「MC 对拍留证」)都不算。禁拿 AGENTS.md「新功能必配新测试」红线代偿——那条只保证写了测试,不保证测得对。2026-10-21 前的旧卡缺对照表 → 停工,退回写卡段补,补完再开工。**判据出处锚(2026-11-05 立,2026-11-09 内容化改版):对照表「需求点」格须带 `<现行文档相对路径>「节名」<行关键词>` 判据出处锚(机检=pipeline_gate C5:内容锚形态唯一+节名在档+关键词命中节内,行号形态出现即红)——行缺锚或锚不可核=停工呈报退写卡段**(test-conventions §8.3)。 - **自洽扫描(轻量,非拷打)**:声明零待裁点≠逻辑无冲突——读卡后快速核三类:①需求卡片内部矛盾(范围/契约/估时/裁决记录互相打架);②需求卡片与 roadmap 行冲突(两处说法不一致);③事实抽查——从需求卡片「现状考证」里抽 3-5 处关键 file:line 到现行代码核对(防需求卡片成文后代码已被其他批改掉,需求卡片变质)。发现疑似冲突 → 逐条列单呈报(哪里矛盾/两种读法各是什么/建议哪边改),**用户裁决后才开工**;零发现则直接通过,不为此拉长开工。全量拷打(/grilling)不在此步做——那是需求卡片成文时的责任,这里只兜网;但**本步必查卡里留没留复核的记录**(见下条),记录不在=上游没跑,停工退写卡段。 - **复核记录缺失(2026-11-05 用户立规)**:需求卡片内没有「复核记录」节、或该节申报的复核报告文件在 `reports/` 盘上不存在 → 不过,停工呈报退回写卡段。本步不代跑复核、不代补记录、不把缺记录的卡当旧卡放行;生效=卡片文件名日期 ≥2026-11-06(与 `tools/pipeline_gate.py` 该条卡片判据同口径),更早的卡不回头改。 - **真人检测遗留项不算门(2026-10-12 用户立规)**:往期迭代/批次登记未验的实机目检项(体验验证清单/实现报告总清单在册)不构成开工阻塞——开工呈报带一句提醒即可,禁为此停工等验。 diff --git a/.zcode/skills/req-card/SKILL.md b/.zcode/skills/req-card/SKILL.md index 8929fdb9..adb1691a 100644 --- a/.zcode/skills/req-card/SKILL.md +++ b/.zcode/skills/req-card/SKILL.md @@ -1,6 +1,6 @@ --- name: req-card -description: g-plan2(Dungeon Sweeper)仓库写需求卡片的固定流程与结构。当用户要求起草/修订需求卡片、给迭代需求写实施文档、或迭代规划进入写卡阶段时使用。固化需求卡片必备结构——尤其「关联文档同步面」必填节(2026-10-17 文档同步闸 v3:卡片服务的是**代码实现批**,该批禁写 `design/` 与根规则文件,要改文档的点一律列进 `reports/` 反哺点清单,用户在会话中裁决后归文档批落文)、「改动—验收对照表」(2026-10-11 立,2026-10-21 升级:每个需求点与每个行为改动都必须有真实入口断言和判据绑定面;无验收标准的需求点=卡片不成立,/iter 开工门同规拦截)与「落位与可复用性预检」必填节(2026-10-21 立:新增文件/函数/数据件前先核仓库既有实现,能复用不新增,落点唯一、禁散落 helper、跨层交互显式声明)、「实现规范预算」必填节(2026-10-27 迭代 39 实证立规:新增件接口块/成员面先对 gdstyle 默认阈值做预算——公开方法 ≤20、类变量 ≤15、迁移函数对账基线键,超了写卡段拆件,例外走显式申报+用户特批,禁把超预算面带进实现段)与「拆分边界纪律」结构类卡必填条款(2026-10-28 用户裁立:拆分边界沿职责轴不沿阈值轴——拆出单元须有职责语句/单一变化原因/集体身份,凑计数袋禁、阈值只作发现信号、拆不出内聚单元停卡呈报走豁免通道,判据权威=code-conventions §1.1)。任务卡 T0..Tn 的步骤写作遵循 superpowers:writing-plans 方法论(2026-10-19 起按本项目适配内联:卡前文件结构图/范围检查/任务右尺寸/步骤粒度/步骤内容四分/接口声明/禁行句式/自审六查)。复核门含判据出处行锚逐行实读(2026-11-07 起,对照表每行锚所指文档行实读核句子在位且内容匹配——机检 C5 只查存在性)与引擎技术面三查(2026-11-04 起,godot-master 窄口径:NEVER/Gotchas/性能预算+按需领域 reference,权威仍在项目规范)。复核发现按四类去向处置(2026-11-05 立:自判=查规范或查代码有唯一答案,复核者自己改卡;补写=卡里漏写,回炉补全;待裁=多种做法都不违规且代价不同,才交用户;退回上游=文档线或美术线未闭合、或架构与代码规范本身冲突);卡片必带「复核记录」节(缺节=不成立,机检=pipeline_gate),复核先于提交、提交先于合回,顺序没走完禁对用户称完成。 +description: g-plan2(Dungeon Sweeper)仓库写需求卡片的固定流程与结构。当用户要求起草/修订需求卡片、给迭代需求写实施文档、或迭代规划进入写卡阶段时使用。固化需求卡片必备结构——尤其「关联文档同步面」必填节(2026-10-17 文档同步闸 v3:卡片服务的是**代码实现批**,该批禁写 `design/` 与根规则文件,要改文档的点一律列进 `reports/` 反哺点清单,用户在会话中裁决后归文档批落文)、「改动—验收对照表」(2026-10-11 立,2026-10-21 升级:每个需求点与每个行为改动都必须有真实入口断言和判据绑定面;无验收标准的需求点=卡片不成立,/iter 开工门同规拦截)与「落位与可复用性预检」必填节(2026-10-21 立:新增文件/函数/数据件前先核仓库既有实现,能复用不新增,落点唯一、禁散落 helper、跨层交互显式声明)、「实现规范预算」必填节(2026-10-27 迭代 39 实证立规:新增件接口块/成员面先对 gdstyle 默认阈值做预算——公开方法 ≤20、类变量 ≤15、迁移函数对账基线键,超了写卡段拆件,例外走显式申报+用户特批,禁把超预算面带进实现段)与「拆分边界纪律」结构类卡必填条款(2026-10-28 用户裁立:拆分边界沿职责轴不沿阈值轴——拆出单元须有职责语句/单一变化原因/集体身份,凑计数袋禁、阈值只作发现信号、拆不出内聚单元停卡呈报走豁免通道,判据权威=code-conventions §1.1)。任务卡 T0..Tn 的步骤写作遵循 superpowers:writing-plans 方法论(2026-10-19 起按本项目适配内联:卡前文件结构图/范围检查/任务右尺寸/步骤粒度/步骤内容四分/接口声明/禁行句式/自审六查)。复核门含判据出处锚逐行实读(2026-11-07 起;2026-11-09 内容锚改版后按索引实读——节名定位、行关键词命中行,核句子在位且内容匹配——机检 C5 核到关键词命中节内粒度、语义错位归实读)与引擎技术面三查(2026-11-04 起,godot-master 窄口径:NEVER/Gotchas/性能预算+按需领域 reference,权威仍在项目规范)。复核发现按四类去向处置(2026-11-05 立:自判=查规范或查代码有唯一答案,复核者自己改卡;补写=卡里漏写,回炉补全;待裁=多种做法都不违规且代价不同,才交用户;退回上游=文档线或美术线未闭合、或架构与代码规范本身冲突);卡片必带「复核记录」节(缺节=不成立,机检=pipeline_gate),复核先于提交、提交先于合回,顺序没走完禁对用户称完成。 --- # 需求卡片写作规范(g-plan2) @@ -37,7 +37,7 @@ description: g-plan2(Dungeon Sweeper)仓库写需求卡片的固定流程与 5. **范围边界**——做什么不做什么;明示不收件的去向(待办清单登记/后续批)。 6. **关联文档同步面(必填,2026-10-17 改口径:实现批禁写文档)**——三列:文档|关联点(本批实现会改变它的哪条陈述)|同步义务。同步义务分三层标注:**设计权威文档**(GDD/art-bible)与**机械面文档**(roadmap 行/术语表/体验验证清单/README)对代码实现批**一律不直改**——实现批**禁写 `design/` 整个目录与根规则文件**,把该改哪一节、改成什么、依据是什么逐条列进 `reports/iter-反哺点-<日期>.md`,由用户在会话中裁决后归文档批落文(不设文档 skill,文档靠会话讨论落地)。实现批唯一可写目录=`reports/`(2026-10-18 用户裁:根目录会话状态文件已废除,无任何例外)。写卡时就要把「实现会影响哪些文档的哪些说法」查全;查不出也要写「无关联文档」四字,不许省略本节。**机检(2026-10-18 卡片冲突修订批补)**=`tools/pipeline_gate.py` 判据 C1「文档义务口径」:同步面表内目标格指向 `design/`(含 `../gdd/` 等相对写法)或根规则文件、而义务格仍写「随批」者红——旧口径措辞「机械面随批」自 2026-10-17 起作废,写卡禁沿用;生效=文件名日期 ≥2026-10-17。 7. **任务卡 T0..Tn**——逐卡估时;**末卡必含「产出物落位卡」**:轻闸全绿后、合并前,把 `reports/` 两份写齐——实现报告(各卡状态+实机目检总清单+遗留读数义务+实现决定记录)、反哺点清单(同步面所列每条都要有落点),方算收口。**禁把任何 `design/` 文件或根规则文件的编辑写进实现批的任务卡**(那是文档批的活)(AGENTS.md 批次工作流 §3.13)。(T 卡内步骤说明的写作纪律见下文「任务卡写作纪律」节,2026-10-19 立。) -8. **验证闸(改动—验收对照表,2026-10-11 立,2026-10-21 升级;2026-10-28 判据口径换代)**——每个需求点列明验收测试内容;每个行为改动也要有一行。表列至少七格:需求点|改动(文件:行/行为)|验收测试(名称+落点+尾缀)|层级(单元/接口/集成/探针)|真实入口|判据绑定面|能力行(2026-10-29 起:`既有:<能力名>/新增:<能力名>`;两形态的名称都须在 `game/tests/README.md` 能力表在场,机检=pipeline_gate)。**能力行当场入表(2026-10-29 用户裁,废「滞后一个迭代」)**:写卡时同批维护能力清单(`game/tests/README.md`,四列=能力|系统|真实入口|代表用例)——本批新增能力当场增行(真实入口取自设计文档已定的入口;代表用例=本卡定死的计划测试 `文件:函数` 名);受影响存量行(入口/用例名变更)同批更新;能力退役删行。**实现照单落名**:测试函数名以清单为唯一依据,名实不符=本卡没写清=停卡退回;实现批禁写 README 的红线不变,批末收尾只核对表上名字与实际落地一致(改名则回表)。落点位置二选一:写在对应 T 卡里,或集中列在验证闸节逐条编号、由 T 卡交叉引用。**每个需求点至少一行;每行必须有真实入口和判据绑定面——缺任一项=该需求点未验收,卡片不成立**。**判据出处行锚(2026-11-05 起,对文件名日期不早于该日的卡生效)**:「需求点」格每行必须带判据出处行锚——该行验收判据所依据的现行文档句子,格式 `<文档相对路径>:<行号>`(如 `design/gdd/ux/camp.md:16`);已退役卡片不算现行文档;规格缺席写不出锚=停卡退回需求澄清(test-conventions §8.3,机检=pipeline_gate C5)。画面类需求的锚指向 ux/ 文档内嵌预览节的判据句(预览图=设计段已人审的目标画面效果图,也是实现批基线冻结时用户对照的参照——test-conventions §8.2)。**基线审核关卡特殊标注(2026-11-08 用户立)**:需求点触碰渲染黄金图基线(新增锚面/换代/迁移/容差修订)时,该行验收标准必须显式标注「触发基线审核关卡」——基线逐张呈报用户审核确认后才入库生效,T 卡步骤须含呈报审核点;漏标=复核门退回补写(test-conventions §8.2 审核关卡)。承接 AGENTS.md 硬红线「新功能必配新测试」:那条只兜「有没有」,本表兜「测得对不对、是不是钉在这个改动上」——写卡期不定稿,实现期就自由发挥。 +8. **验证闸(改动—验收对照表,2026-10-11 立,2026-10-21 升级;2026-10-28 判据口径换代)**——每个需求点列明验收测试内容;每个行为改动也要有一行。表列至少七格:需求点|改动(文件:行/行为)|验收测试(名称+落点+尾缀)|层级(单元/接口/集成/探针)|真实入口|判据绑定面|能力行(2026-10-29 起:`既有:<能力名>/新增:<能力名>`;两形态的名称都须在 `game/tests/README.md` 能力表在场,机检=pipeline_gate)。**能力行当场入表(2026-10-29 用户裁,废「滞后一个迭代」)**:写卡时同批维护能力清单(`game/tests/README.md`,四列=能力|系统|真实入口|代表用例)——本批新增能力当场增行(真实入口取自设计文档已定的入口;代表用例=本卡定死的计划测试 `文件:函数` 名);受影响存量行(入口/用例名变更)同批更新;能力退役删行。**实现照单落名**:测试函数名以清单为唯一依据,名实不符=本卡没写清=停卡退回;实现批禁写 README 的红线不变,批末收尾只核对表上名字与实际落地一致(改名则回表)。落点位置二选一:写在对应 T 卡里,或集中列在验证闸节逐条编号、由 T 卡交叉引用。**每个需求点至少一行;每行必须有真实入口和判据绑定面——缺任一项=该需求点未验收,卡片不成立**。**判据出处锚(2026-11-05 立;2026-11-09 用户裁内容化改版——内容节锚唯一形态,行号形态废止)**:「需求点」格每行必须带判据出处锚——该行验收判据所依据的现行文档句子,格式 `<文档相对路径>「节名」<行关键词>`(如 `design/ux/camp.md「Navigation Position」开始冒险`);节名=判据句所在节标题词(首段「·」前须命中目标文档标题行),行关键词=判据句上的无空白子串(须落在节块内);锚指向内容不指向行号,文档增删行不牵动卡片;已退役卡片不算现行文档;规格缺席写不出锚=停卡退回需求澄清(test-conventions §8.3,机检=pipeline_gate C5:内容锚形态唯一+节名在档+关键词命中节内,行号形态出现即红)。画面类需求的锚指向 ux/ 文档内嵌预览节的判据句(预览图=设计段已人审的目标画面效果图,也是实现批基线冻结时用户对照的参照——test-conventions §8.2)。**基线审核关卡特殊标注(2026-11-08 用户立)**:需求点触碰渲染黄金图基线(新增锚面/换代/迁移/容差修订)时,该行验收标准必须显式标注「触发基线审核关卡」——基线逐张呈报用户审核确认后才入库生效,T 卡步骤须含呈报审核点;漏标=复核门退回补写(test-conventions §8.2 审核关卡)。承接 AGENTS.md 硬红线「新功能必配新测试」:那条只兜「有没有」,本表兜「测得对不对、是不是钉在这个改动上」——写卡期不定稿,实现期就自由发挥。 - **测试方式两分法**(2026-10-11 用户定):能力验证=调试接口直改游戏数据(改钥石/槽位/解锁状态等,不走正常资源积累流程,沿用现役 DebugOverlay/DS_DEBUG 门控);正常流程体验验证=用户目检,观测项写进 `reports/iter-实现报告-<日期>.md` 的实机目检总清单(2026-10-17 起:`体验验证清单.md` 属设计文档,实现批禁写,入册该体验验证清单的条目作为反哺点由文档批落)。每张卡写明哪些点归调试接口验、哪些点归用户目检验。**用户目检一律「登记不阻塞」(2026-10-12 用户立规)**:登记完成即卡内义务了结,验收时间由用户自行安排,不得作为批末收尾、合并或下一迭代开工的前置条件。 - **闸口径(2026-10-17 改按域;2026-10-26 判据改按文件性质)**:轻闸/重闸按 AGENTS.md 分级周期口径——**重闸=`tools/run_all_gates.sh` 按本批改动域选档**(改动含 `game/` 下非 `.md` 的行为载体 → `--code`;只有文档件——`game/` 内 `.md`、`design/`、根规则文件、`tools/` 工具脚本 → `--docs`;两类都有或改闸件本身 → 不带参数全量),所选域全绿才合并。**卡内禁写死闸件名单与"全量档"字样**(域划分的唯一出处在脚本里);批末四闸语义改述为「代码域闸全绿(冒烟+单元+探针+渲染/静态)+改前改后读数对拍」。改完即测铁规照履行:卡内改动落笔即测自己改过的那部分,不请示。 - **回归措辞模板(2026-10-14 闸机轮次纪律,AGENTS.md 同源)**:禁用「每步对拍+全量回归」「每轮全量回归」类措辞——会被执行侧解读成每次修复跑全套;改用模板句:「里程碑步(波/T 段)出口跑一次全套闸;波内修复只做出红最小单元的最窄确认;新增测试/工具先行孤立验证再并入全套」。 @@ -105,7 +105,7 @@ description: g-plan2(Dungeon Sweeper)仓库写需求卡片的固定流程与 - 平实中文,禁自造缩写与名词堆叠;仓库既有术语照用。 - 估时给区间+切分预案(超软盒预挂)。 - **任务卡自审七查(2026-10-19 立五查,2026-10-21 补第六查,2026-10-27 补第七查;借自 superpowers:writing-plans 自审节适配)**:任务卡写完、交 grilling 复核前必跑——①规格覆盖:逐条过「目标与完成定义」的规格项/需求点,每条都能指到一张 T 卡,并指到验收对照表的一行,指不到的补卡/补行;②步骤扫描:每步只能让实施者写出一个合情合理的东西、且一步不多带——不决定事的行是缺口,签名与验收已定的函数体是抄写,两样都就地改;③类型一致性:后卡引用的签名/属性名与早卡定义逐字一致;④审查焦点+改动覆盖:规格暗示、但没有任何 T 卡测试覆盖的失败模式——对照「验证闸」节逐条过,把最可能坑到玩家的列出来、挂到责任 T 卡补验收条目;同时核文件结构图里的每个行为改动都能指到对照表行,指不到的补测试或标非行为改动;查完确实没有才写「无」;⑤篇幅比例:卡片比它实现的规格长几倍=在抄程序,代码块占大半就把函数体换成签名+断言名,再验每步仍无歧义;⑥落位与复用(2026-10-21 用户立规):逐条过本批每个新增文件、新增函数、新增数据件——**盘上是否已有做同样事的东西(grep 同职责实现、grep 同名与同义标识符)?该功能是否已有唯一落点?同一事实是否只在一处定义、有无 helper 散落「就近的文件」?新增件之间的调用路径与跨层出口是否显式声明?**答案写进卡内「落位与可复用性预检」节并与文件结构图对得上(标「新增」的必须能指到不能复用的理由);对不上就改成复用既有件、或把重复的落点并进唯一一处;⑦指标预算(2026-10-27 迭代 39 实证立规):逐条过本批每个新增文件——「实现规范预算」节三查一查的数字与接口块/文件结构图实数一致(数接口块 func 行、数成员 var 行、迁移函数逐个对 `tools/gdstyle_baseline.txt` 源键),少报、漏对账或预算节缺失的回炉补节,存量触面写明「S13 键只降不升」预期。七查发现问题就地改完再交复核,不用再自审一轮;自审在 grilling 之前跑,不替代 grilling 对抗复核。 -- **grilling 复核门(2026-10-10 用户立规;2026-11-05 补处置登记义务)**:卡片成文后必经 grilling 多轮复核,裁决全落、零待裁点,卡片才算成立;每轮发现与处置逐条写进卡内「复核记录」节(必备结构第 17 节)。**复核审点含验收清单:逐需求点过「测什么/怎么测/谁验」三问,答不上来的需求点回炉(2026-10-11 用户立规);并核对照表两端是否对得上、真实入口是否绕过改动点、判据绑定面是否绑被测改动特有的可观测提交面(2026-10-21 立);再核「落位与可复用性预检」节与文件结构图是否对得上——每个标「新增」的件都要有不能复用的理由与唯一落点,给不出的回炉改成复用(2026-10-21 用户立规);再核「实现规范预算」节数字与接口块/文件结构图实数一致——少报方法数、漏迁移函数对账、预算节缺失的回炉(2026-10-27 用户立规);再核「拆分边界纪律」条款在位、每个拆出单元有职责语句与集体身份——凑计数袋形态回炉(2026-10-28 用户立规);再核「验证闸」对照表每行**判据出处行锚逐行实读**(2026-11-07 用户立)——打开锚所指文档行,核句子在位且内容与该行判据匹配;机检 C5 只查存在性、查不出内容错位,写卡后文档被其他批改动会使锚漂移(2026-11-07 退役卡 ux 四锚漂移实证);锚失位=发现清单一条,按四类分流处置;再核引擎技术面三查(接口与边界见下条):①卡内签名与实装步骤涉及的 Godot API 在 4.7 存在且行为如卡所述;②实装步骤不踩 godot-master NEVER list 与 Gotchas;③热路径/批量/线程形态匹配其性能预算——产出发现清单,逐条按「复核发现四类分流」处置(2026-11-04 用户立规;2026-11-05 补去向口径:只有待裁类归用户裁决,自判与补写两类由复核者自己落卡,退回上游类退对应段)。** +- **grilling 复核门(2026-10-10 用户立规;2026-11-05 补处置登记义务)**:卡片成文后必经 grilling 多轮复核,裁决全落、零待裁点,卡片才算成立;每轮发现与处置逐条写进卡内「复核记录」节(必备结构第 17 节)。**复核审点含验收清单:逐需求点过「测什么/怎么测/谁验」三问,答不上来的需求点回炉(2026-10-11 用户立规);并核对照表两端是否对得上、真实入口是否绕过改动点、判据绑定面是否绑被测改动特有的可观测提交面(2026-10-21 立);再核「落位与可复用性预检」节与文件结构图是否对得上——每个标「新增」的件都要有不能复用的理由与唯一落点,给不出的回炉改成复用(2026-10-21 用户立规);再核「实现规范预算」节数字与接口块/文件结构图实数一致——少报方法数、漏迁移函数对账、预算节缺失的回炉(2026-10-27 用户立规);再核「拆分边界纪律」条款在位、每个拆出单元有职责语句与集体身份——凑计数袋形态回炉(2026-10-28 用户立规);再核「验证闸」对照表每行**判据出处锚逐行实读**(2026-11-07 用户立)——按锚索引(节名定位、行关键词命中行)打开文档节句,核句子在位且内容与该行判据匹配;机检 C5 核到「关键词命中节内」粒度、查不出语义错位(句被改写而关键词仍为其子串时机器盲),实读兜语义;锚失位=发现清单一条,按四类分流处置;再核引擎技术面三查(接口与边界见下条):①卡内签名与实装步骤涉及的 Godot API 在 4.7 存在且行为如卡所述;②实装步骤不踩 godot-master NEVER list 与 Gotchas;③热路径/批量/线程形态匹配其性能预算——产出发现清单,逐条按「复核发现四类分流」处置(2026-11-04 用户立规;2026-11-05 补去向口径:只有待裁类归用户裁决,自判与补写两类由复核者自己落卡,退回上游类退对应段)。** - **引擎技术面复核接口(2026-11-04 立,godot-master 窄口径接入)**:本条是 req-card 对 godot-master 技能的唯一引用面,四条收窄——①取用白名单:只取其 SKILL.md 内三块——Part 4 NEVER list(33 条)、Part 8 Gotchas(8 条)、Part 5 性能预算表;卡涉及具体领域(物理/动画/UI/存档/寻路等)时另按其 Part 2 决策矩阵加载与改动面直接相关的 reference,至多 2 个;禁加载工作流链、genre 蓝图与其余整库。②权威边界:只取引擎事实(API 行为、已知坑、预算数字),不取其工程组织主张(目录结构、autoload/signal bus 模式)——架构/分层/数值判断权威仍是本项目 architecture.md、code-conventions 与 data/tables;两者冲突时项目规范赢,冲突本身当轮作为待裁点呈报用户,禁按任一方默默改卡。③输出形态:复核产出=发现清单(卡内位置+违反条目号如 NEVER-7/Gotcha-1+一句依据)+四类去向之一,其中待裁与退回上游两类不改写方案,自判与补写两类的处置就是把卡改对;引用条目须给编号,判不了标「未判」禁硬判。④成本约束:成本地板=hub SKILL.md 单文件;卡内 T 步不含节点/信号/Tween/Resource/物理/线程/渲染面时只跑②清单对照,不加载领域 reference;每个领域 reference 一轮复核只加载一次。 - **复核发现四类分流(2026-11-05 用户立规)**:复核者每拿到一条发现,先问「答案从哪来」,四选一登记去向(写进卡内「复核记录」节的去向格);前两类的处置由复核者自己完成,禁转成问句向用户求裁: - **自判**——查权威文档或查代码现状就能得到唯一答案。权威文档=本卡设计事实源那一份 owner 文档+`design/engineering/` 五份规约与 architecture+术语表+在册先例(git 提交信息与库内已入库实现)。处置=复核者当场下结论并把卡改成那个答案,处置格写结论+`文件:行号` 依据。**禁问用户**:这类问题问出去等于把可查的事推给人决策。 diff --git a/design/engineering/process-conventions.md b/design/engineering/process-conventions.md index fbac578a..6a604993 100644 --- a/design/engineering/process-conventions.md +++ b/design/engineering/process-conventions.md @@ -23,7 +23,7 @@ |---|---|---|---| | 一·登记 | 无(闸管格式) | 待办清单条目 | 条目=标题登记元数据(日期/来源/可选优先级)+正文四属性(实况/缺口/改动面/状态);标题登记后不再变,正文随进程演进。格式与状态机权威=doc-conventions 第 12 节 | | 二·文档设计/美术设计 | doc-design(文档线,兼任反哺点写入)/asset-ingest(美术录入;样张素材由用户主导产出) | GDD 文档或 art-bible/过审样张素材;画面类需求另出预览图(文档线,2026-11-05 用户裁) | 用户提起或从待办清单取出;会话内进行、用户主导、禁无监管自跑;经用户点头确认心智一致才许写入文档;完成判据=待裁点清零,带未裁点的是讨论稿;设计线闭合凭据记入待办清单实况清单(文档线=文档路径+版本号,美术线=art-bible 条款版本);缺哪条线写在缺口属性,闭合与否写在状态段。画面类需求(新增画面要素/布局/配色/动效等触碰画面呈现规格的改动)设计段先出预览图=目标画面的 HTML/SVG 效果图(diagram-design 通道,AGENTS.md 图优先的同款载体),经用户人审通过才许进写卡段;预览图内嵌对应 ux/ 规格文档并随附像素级视觉判据句(§7 第 2 条同款写法);缺陷修复以现行规格与在库基线为准,不触发新预览 | -| 三·写需求卡片 | req-card | 需求卡片 | 设计线闭合后用户发令;新玩法/新系统/新内容必须有设计定稿前置,例外=需求性工程条目(缺陷修复/重构等改游戏行为)凭实况里的证据指认跳过设计线;配套维护类(工程债/测试基建/工具维护,不动游戏行为)=工程改动直改类,不走本段,由用户发令直改;卡片必经 grilling 多轮复核、零待裁点才成立;复核发现按四类去向处置(2026-11-05 用户立规,定义在 req-card 技能「复核发现四类分流」:自判=查权威文档或查代码现状有唯一答案,复核者自己下结论改卡;补写=卡里漏写,回炉补全;待裁=几种做法都不违规且代价不同、影响玩法取向,才交用户;退回上游=文档设计线未闭合、美术设计线未闭合、或架构与代码规范本身冲突,停笔退对应段);成立凭据=卡内「复核记录」节(2026-11-06 用户裁:不另设复核报告文件),顺序未走完禁对用户称完成、禁落 commit(同 §1 第 2 条卡片复核前置判据);写完在待办清单状态记「已写卡」,卡片路径记入实况清单(防遗忘);画面类需求卡片必引设计段已人审的预览图(验收判据的判据出处行锚指向 ux/ 内嵌预览节,test-conventions §8.3 锚口径不变) | +| 三·写需求卡片 | req-card | 需求卡片 | 设计线闭合后用户发令;新玩法/新系统/新内容必须有设计定稿前置,例外=需求性工程条目(缺陷修复/重构等改游戏行为)凭实况里的证据指认跳过设计线;配套维护类(工程债/测试基建/工具维护,不动游戏行为)=工程改动直改类,不走本段,由用户发令直改;卡片必经 grilling 多轮复核、零待裁点才成立;复核发现按四类去向处置(2026-11-05 用户立规,定义在 req-card 技能「复核发现四类分流」:自判=查权威文档或查代码现状有唯一答案,复核者自己下结论改卡;补写=卡里漏写,回炉补全;待裁=几种做法都不违规且代价不同、影响玩法取向,才交用户;退回上游=文档设计线未闭合、美术设计线未闭合、或架构与代码规范本身冲突,停笔退对应段);成立凭据=卡内「复核记录」节(2026-11-06 用户裁:不另设复核报告文件),顺序未走完禁对用户称完成、禁落 commit(同 §1 第 2 条卡片复核前置判据);写完在待办清单状态记「已写卡」,卡片路径记入实况清单(防遗忘);画面类需求卡片必引设计段已人审的预览图(验收判据的判据出处锚指向 ux/ 内嵌预览节,test-conventions §8.3 锚口径不变) | | 四·迭代编排 | iter-plan | roadmap 迭代行 | **开工前预检(2026-11-07 用户立)**:收令点名拟编卡集后、五查与落表前,对卡集做一轮只读事实面预检——八类检查、P1/P2/P3 分级去向与只读子代理执行方式=iter-plan 技能「第 3 步·开工前预检」;P1 红项停编排、退回写卡段,禁编入。预检目标=尽量减少实现期停工、非杜绝——环境漂移与卡片并行修改仍可在实现期停工,由实现段异常分级与 iter T0 开工日窄复核兜底。编排五查:①每卡卡片文件存在 ②每卡设计闭合凭据齐(或需求性工程条目的证据指认)③估时与冻结线——所选卡估时按区间**中值**求和(单位工作日、写精确值不取整):**卡片任何工作量均可编入**(2026-10-25 用户立:工作量限制属迭代层、非卡片层);编入后迭代总量 <5 个工作日=迭代行状态「冻结待凑批」、不可开工,凑批 ≥5 后由编排段改「待开工」(迭代体量偏好,2026-10-21 用户立、2026-10-25 改冻结制);5–10 个工作日为常规区间;超过 10 个工作日须经用户确认(确认前呈报整批/拆批两案等裁,禁自行拆分或塞入),确认后迭代行随带日期特批标记;超过 20 个工作日禁止编(硬上限,用户确认也不放行,必须拆批)④每卡复核记录在位(2026-11-05 用户立规;2026-11-06 用户裁凭据换代——复核凭据=「复核记录」节自身,不另查报告文件)——卡内有「复核记录」节;缺节或节内任一条发现没有去向标记则呈报退回写卡段,禁编入,本段不代跑复核也不代补记录(生效=卡片文件名日期 ≥2026-11-06,旧卡不回头改)⑤写完 roadmap 行后跑流水线闸确认绿;编入未完成迭代,新开迭代行经用户确认 | | 五·实现 | iter | 代码与配置,可运行的游戏 | 需求卡片永不单独施工,统一由用户指定迭代号触发(=U0 开工令),按 iter 技能与本文 §3 执行;**本段是代码实现批:禁写 `design/` 与根规则文件,产出物只落 `reports/`(见 §3 第 12 条)**;设计权威文档(GDD/art-bible)批内一律不更新;完成人闸=实机目检清单+实现决定记录写齐即完成批内义务;画面类需求实现批另按 test-conventions §8.2 黄金图基线冻结口径执行(实跑截图入基线前用户逐张审核确认+审核记录落档,此后渲染闸自动盯);**golden 基线改动批(含非卡片批的迁移/重构/容差修订)merge 前须用户审核通过(test-conventions §8.2 审核关卡),未审核的基线禁合回** | diff --git a/design/engineering/test-conventions.md b/design/engineering/test-conventions.md index b8830a8a..22133feb 100644 --- a/design/engineering/test-conventions.md +++ b/design/engineering/test-conventions.md @@ -97,7 +97,7 @@ - **接口**:模块边界的公开契约——数据表加载、存档与断点、事件载荷、命令接口;测试从公开入口进出。接口级断言随单元套件落(`unit/contracts/`),不另设承载目录。 - **跨宿主**:跨宿主的接线、持久、生命周期——例如 LevelRunner 把 level_counters 传给 BattleOrchestrator、两场战斗共享同一个桶、断点续玩;测试必须实例化真实宿主链,禁止用裸 EffectEngine 代替。断言载体归单元层跨系统闭环套件(§1.1 三元组表),验收入口不变。 - **探针/golden**:玩家可达性与观感;真实实例化场景、驱动真实输入。 -- **golden 测试项扩项(2026-11-05 立)**:触碰画面呈现规格的需求批(新增画面要素/布局/配色/动效;判据=设计段出了预览图),实现段把该画面纳入渲染闸机器面:截图采集清单扩项+实跑截图冻结进 `game/tests/golden/`(基线属入库测试资产,render_gate.sh 在册例外)。黄金图=游戏真实渲染截屏冻结的逐像素基准,比对器与容差口径见 render_gate.sh 头注释(脚本即清单,本文不另列)。基线冻结(新建与换代同口径)=**用户逐张审核确认后执行**,触发原因写进当批提交说明(`tools/golden_baseline_refresh.sh` 现役义务);此后渲染闸逐像素自动盯、零人工。预览图(HTML/SVG 效果图)与引擎渲染是两套管线,禁直接充当比对基线——预览图只作人审参照与验收判据句的出处(判据出处行锚指向 ux/ 内嵌预览节);缺陷修复以现行规格与在库基线为准,不触发新预览。 +- **golden 测试项扩项(2026-11-05 立)**:触碰画面呈现规格的需求批(新增画面要素/布局/配色/动效;判据=设计段出了预览图),实现段把该画面纳入渲染闸机器面:截图采集清单扩项+实跑截图冻结进 `game/tests/golden/`(基线属入库测试资产,render_gate.sh 在册例外)。黄金图=游戏真实渲染截屏冻结的逐像素基准,比对器与容差口径见 render_gate.sh 头注释(脚本即清单,本文不另列)。基线冻结(新建与换代同口径)=**用户逐张审核确认后执行**,触发原因写进当批提交说明(`tools/golden_baseline_refresh.sh` 现役义务);此后渲染闸逐像素自动盯、零人工。预览图(HTML/SVG 效果图)与引擎渲染是两套管线,禁直接充当比对基线——预览图只作人审参照与验收判据句的出处(判据出处锚指向 ux/ 内嵌预览节);缺陷修复以现行规格与在库基线为准,不触发新预览。 - **golden 基线冻结审核关卡(2026-11-08 用户立)**:基线=人定标准、机器守标准——**任何基线的新建/换代/迁移/容差修订,呈报用户逐张审核、确认后才能提交入库生效**;该关卡适用于两类批:①画面类需求批(候选基线对照该卡预览图逐张呈报)②**非卡片批的基线操作**(目录重构/平台迁移/容差修订等工程批——同样逐张呈报审核,禁以「纯搬运/纯工程」为由跳过)。确认记录登记于 `game/tests/golden/README.md` 审核记录节(审核人+时间+基线清单),**未审核的基线禁合回**。机器侧前置:探针自检 PASS(结构断言在案)才允许出候选图,采集失败不得送审。基线**跨平台单套**(同日用户裁:跨平台渲染必须一致,全平台对拍同一份基线,跨平台字形锯齿噪声由容差带吸收,禁以加基线方式消化差异;细则=golden/README「基线冻结与审核」节)。 分层不是形式。改动发生在哪一层,验收就必须从那一层的真实入口进入。测试绕过了改动点,就不算这个改动的验收——这正是「断言存在、接线坏了却不红」的来源。 @@ -115,9 +115,9 @@ - **反向**:diff 里每个行为改动至少一行;没有对应行的改动,必须写明「非行为改动」或「由第 X 行覆盖」。 - **测试侧**:新增或改写的每条断言至少挂一行;挂不上的孤儿断言删掉或补挂到需求点。 -**判据出处行锚(2026-11-05 立,自 2026-11-05 起对文件名日期不早于该日的需求卡片生效;旧卡不回头改,被编入迭代开工前由写卡段按本粒度补挂)**:对照表「需求点」列每行必须带**判据出处行锚**——该行验收判据所依据的现行文档句子,格式「`<文档相对路径>:<行号>`」。现行文档=`design/` 全域现行文档(含 `ux/` 交互规格与 art-bible 的判据行);已退役的需求卡片不是现行文档,不得充当判据出处。作用=断言预期值从规格句抄出,不从实现反推:实现行为与规格句冲突时断言红;规格缺席的行写不出锚,即停卡退回写卡段(那是需求澄清缺口,不是测试缺口)。机检=`tools/pipeline_gate.py` 判据 C5(锚格式与指向存在性,按卡文件名日期分流)+`tools/capability_audit.py` 链式锚检查(断言→套件→能力行→系统文档,见 §8.9)。 +**判据出处锚(2026-11-05 立;2026-11-09 用户裁内容化改版——行号形态废止,内容节锚为唯一形态)**:对照表「需求点」列每行必须带**判据出处锚**——该行验收判据所依据的现行文档句子,格式「`<文档相对路径>「节名」<行关键词>`」。现行文档=`design/` 全域现行文档(含 `ux/` 交互规格与 art-bible 的判据行);已退役的需求卡片不是现行文档,不得充当判据出处。节名=判据句所在节的标题词(节名首段「·」前须命中目标文档标题行);行关键词=判据句上的无空白子串(须落在该节块内)。锚指向内容不指向行号——文档增删行不牵动锚与测试代码,只有判据句内容真被改动才使锚失配;失配(节名不在档/关键词不命中)=红,改动该句的文档批同批改锚。作用=断言预期值从规格句抄出,不从实现反推:实现行为与规格句冲突时断言红;规格缺席的行写不出锚,即停卡退回写卡段(那是需求澄清缺口,不是测试缺口)。机检=`tools/pipeline_gate.py` 判据 C5(内容锚形态唯一+节名在档+关键词命中节内,核验口径归 `tools/anchor_util.py` 共用件;行号形态出现即红)+`tools/capability_audit.py` 链式锚检查(断言→套件→能力行→系统文档,见 §8.9)。 -**测试函数的判据出处注记(2026-11-06 立)**:`game/tests/**` 与 `game/probe/**` 内每个**验证函数**(函数体含 `check(`/`check_quiet(`/`_problems.append(`/`push_error(` 判定调用的函数——定义行与 `_check(` 前缀不作判定计)必须带至少一条**判据出处注记**,格式「`# 判据出处: :<行号> <判据一句>`」——指针在前、判据摘要句在后;锚形态两档:行号锚(默认)与节锚(`「节名」<行关键词>`)——所指文档整节重排时同批把行号锚重锚为节锚,免行号漂移(2026-11-07 架构收窄批立),断言预期值的出处随断言走:断言红时读注记即达出处文档句,零查表。指针空间=`design/` 全域现行文档(行为测试锚 owner 系统文档「验收标准」句或 `ux/` 规格句;惯例类测试〔封装扫描、判定通道纪律、驱动契约〕锚规约条款行;测量面驱动契约锚 `game/sim/` 实现件文件头注——规范句在哪锚哪,2026-11-09 架构收敛批立);`game/sim/` 不进扫描面(测量面直构惯例)。与链式锚的分工:链式锚(断言→套件→能力行→系统文档)不变、属义务清单层;本注记属执行证据层、写在断言文件内,非独立账本(§8.9 法则 4 不变)。写新测试函数时当场挂注记;被指规格句改行号时随批维护指针——死指针即红。局限如实声明:注记是被动文本,句内容改而行数不变时机检抓不到(与卡片判据 C5 同限)。机检=`tools/capability_audit.py` 判据出处注记道(覆盖检查+指针存在性;扫描面零文件自检红)。规格缺席写不出锚=发现规格缺口:记发现不造锚、收尾呈报,禁锚到非现行文档凑数。 +**测试函数的判据出处注记(2026-11-06 立;2026-11-09 内容化改版——内容节锚唯一形态)**:`game/tests/**` 与 `game/probe/**` 内每个**验证函数**(函数体含 `check(`/`check_quiet(`/`_problems.append(`/`push_error(` 判定调用的函数——定义行与 `_check(` 前缀不作判定计)必须带至少一条**判据出处注记**,格式「`# 判据出处: 「节名」<行关键词> <判据一句>`」——指针在前、判据摘要句在后;节名与行关键词口径同上(卡片判据锚同款,`game/sim/` 测量面实现件无标题结构,节名与关键词按文件内子串命中),断言预期值的出处随断言走:断言红时读注记即达出处文档句,零查表。指针空间=`design/` 全域现行文档(行为测试锚 owner 系统文档「验收标准」句或 `ux/` 规格句;惯例类测试〔封装扫描、判定通道纪律、驱动契约〕锚规约条款行;测量面驱动契约锚 `game/sim/` 实现件文件头注——规范句在哪锚哪,2026-11-09 架构收敛批立);`game/sim/` 不进扫描面(测量面直构惯例)。与链式锚的分工:链式锚(断言→套件→能力行→系统文档)不变、属义务清单层;本注记属执行证据层、写在断言文件内,非独立账本(§8.9 法则 4 不变)。写新测试函数时当场挂注记;判据句被改动使关键词失配时,改动该句的文档批同批改锚——失配即红。局限如实声明:注记核验到「关键词命中节内」粒度,判据句被改写而关键词仍为其子串时语义漂移机检抓不到,由复核门实读兜(与卡片判据 C5 同限)。机检=`tools/capability_audit.py` 判据出处注记道(覆盖检查+内容锚核验,行号形态出现即红;扫描面零文件自检红)。规格缺席写不出锚=发现规格缺口:记发现不造锚、收尾呈报,禁锚到非现行文档凑数。 **验收档申报(2026-11-04 立,自 2026-11-05 起对文件名日期不早于该日的需求卡片生效;旧卡不回头改)**:每张需求卡片在头部信息区(与设计事实源声明同区)申报一个验收档,三档:高/中/低。判据=失败代价单维——这条改动做错了,后果随存档或结算传播的(存档写读与迁移、RNG 流、战斗结算公式与乘区、经济入账、数值表结构校验)=高;后果玩家可见但不损持久状态的(常规玩法逻辑、门控、交互逻辑、呈现数据面)=中;后果即看即知且无状态残留的(文案、纯呈现样式、布局微调)=低。一张卡触多档按最高档申报;申报由写卡段落笔,用户批卡(U0)时确认或改判。档位只调节 §8.7 审计深度——闸机与 CI 的域划分、选闸算法、全量强制档一概不因档位变化,真实入口、判据绑定面、禁削弱等验收闭合判据全部照旧。未申报档位的卡一律按高档全量审计。机检=`tools/pipeline_gate.py` 判据 C4:卡内须含「验收档:高/中/低」申报行。 @@ -153,7 +153,7 @@ 2. 抽查判据绑定面:断言从真实入口进入、钉在被测改动的特有可观测提交面上,且当轮真实跑批执行过; 3. 检查测试削弱:删除断言、放宽阈值、缩小扫描面、换下层直调,逐处要卡片申报或用户批准。 4. 核对内部字段直查的受控例外:直查行是否已在对照表注明理由(该行为无公开可观测面可钉)。 -5. 核对判据出处:抽查断言的预期值能否从其判据出处行锚(§8.3)的规格句独立写出——预期值只在实现里有的(同义反复,判据镜像实现),判红。 +5. 核对判据出处:抽查断言的预期值能否从其判据出处锚(§8.3)的规格句独立写出——预期值只在实现里有的(同义反复,判据镜像实现),判红。 **审计深度分级(2026-11-04 立)**:审计按卡内申报的验收档(§8.3)逐卡定深度;梯度只落在昂贵的判断件上,机械且堵造假向量的两件(削弱检查、例外核对)三档全保留不抽。中/低档省略的测试复跑以远端 CI 读数为执行证据——`tools/ci_check.sh <合并提交>` 的现查输出(commit+run 号+conclusion)是机器产物,run 号在远端永久可复核,审计报告照抄该行即可;照抄前先核对读数必须是「绿」——「未验」(零触发批跑闸步全跳过)与「不可判」不作证据,那种批的回补办法是等一次含代码面的合回或用户自发全量回归(2026-11-04 用户裁:回执等待件退役,证据由落盘文件改为现查读数;「不采信实现者自述已全绿」的口径不变): diff --git a/game/probe/board_shot_probe.gd b/game/probe/board_shot_probe.gd index d976684d..f63e8adf 100644 --- a/game/probe/board_shot_probe.gd +++ b/game/probe/board_shot_probe.gd @@ -93,7 +93,7 @@ func _mark_domain_counts(view: Node, tag: String) -> Dictionary: func _ready() -> void: -# 判据出处: design/engineering/test-conventions.md:84 (棋盘截图取证——渲染闸采集组) +# 判据出处: design/engineering/test-conventions.md「7. 判定可靠性优先于覆盖率」跑一遍没崩 跑一遍没崩(棋盘截图取证——渲染闸采集组) # 运行前提=窗口化真渲染面(shot_probe 同款护栏——headless 下 frame_post_draw 永不触发+视口纹理恒空) if DisplayServer.get_name() == "headless": print("[board_shot] FAIL — 本探针必须窗口化运行(headless 无渲染面,截图必空);现行事实源=tools/render_gate.sh 取证段") @@ -259,7 +259,7 @@ func _ready() -> void: # 判据:环外径像素 ÷ 格边 落 0.82±1px;封印格最外圈 1px 框最暗值与相邻未封印未开格同位框最暗值差 ≤1/255 #(halo 在 0.455×格边归零——格边框不应被压暗;相邻未开格同砖纹理同套瓦片为无封印参照)。 func _seal_evidence(tag: String, view: Node, settlement: Object, off_img: Image, out: String) -> void: -# 判据出处: design/engineering/test-conventions.md:84 (封印印记像素取证组) +# 判据出处: design/engineering/test-conventions.md「7. 判定可靠性优先于覆盖率」跑一遍没崩 跑一遍没崩(封印印记像素取证组) var ms = settlement.minesweeper var seal_cell := Vector2i(-9, -9) var ref_cell := Vector2i(-9, -9) @@ -367,7 +367,7 @@ func _probe_identity_lookup(c: Vector2i): # 双帧逐像素比对:所有变化像素必须落在生效格的内缘带内 # (de < cell÷8——带外含砖心零侵入=禁整格染色/禁越圈);每个生效格须有实绘像素(不空转)。 func _check_dual_frames(tag: String, view, glow_cells: Dictionary, off_img: Image, on_img: Image) -> void: -# 判据出处: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) +# 判据出处: design/engineering/test-conventions.md「5. 测试函数怎么写——验收清单条目的落码规范」需求卡片 需求卡片(判定上报通道——验证函数组) var board = view.board() if board == null: _problems.append("%s 双帧比对取板失败(view.board() 为 null)" % tag) diff --git a/game/probe/fx_probe.gd b/game/probe/fx_probe.gd index 365a8d6b..3ab801fd 100644 --- a/game/probe/fx_probe.gd +++ b/game/probe/fx_probe.gd @@ -8,7 +8,7 @@ extends Node func _ready() -> void: -# 判据出处: design/gdd/systems/战斗循环/战斗表现.md:148 (结算演出——挖掘期零打扰组) +# 判据出处: design/gdd/systems/战斗循环/战斗表现.md「验收标准」挖掘期零打扰 (结算演出——挖掘期零打扰组) await get_tree().process_frame var problems: Array = [] diff --git a/game/probe/fx_shot_probe.gd b/game/probe/fx_shot_probe.gd index a953779b..728f0b12 100644 --- a/game/probe/fx_shot_probe.gd +++ b/game/probe/fx_shot_probe.gd @@ -21,7 +21,7 @@ var _problems: Array = [] func _ready() -> void: -# 判据出处: design/engineering/test-conventions.md:84 (特效截图取证——渲染闸采集组) +# 判据出处: design/engineering/test-conventions.md「7. 判定可靠性优先于覆盖率」跑一遍没崩 跑一遍没崩(特效截图取证——渲染闸采集组) var args := OS.get_cmdline_user_args() out_dir = args[0] if args.size() >= 1 and args[0] != "" else "user://qa-fx" DirAccess.make_dir_recursive_absolute(out_dir) @@ -108,7 +108,7 @@ func _ready() -> void: func _snap(tag: String) -> void: -# 判据出处: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) +# 判据出处: design/engineering/test-conventions.md「5. 测试函数怎么写——验收清单条目的落码规范」需求卡片 需求卡片(判定上报通道——验证函数组) await RenderingServer.frame_post_draw var img: Image = get_viewport().get_texture().get_image() if img == null or img.is_empty(): @@ -118,7 +118,7 @@ func _snap(tag: String) -> void: func _fail(msg: String) -> void: -# 判据出处: design/engineering/test-conventions.md:56 (判定上报通道——验证函数组) +# 判据出处: design/engineering/test-conventions.md「5. 测试函数怎么写——验收清单条目的落码规范」需求卡片 需求卡片(判定上报通道——验证函数组) _problems.append(msg) push_error("[fx_shot_probe] FAIL — " + msg) get_tree().quit(1) diff --git a/game/probe/layout_probe.gd b/game/probe/layout_probe.gd index e0e8ddf9..21cb817c 100644 --- a/game/probe/layout_probe.gd +++ b/game/probe/layout_probe.gd @@ -19,7 +19,7 @@ var _est_reads: Dictionary = {} # 逐档 13/14 板推定读数留痕(label func _ready() -> void: -# 判据出处: design/gdd/systems/表现与支撑/HUD框架.md:264 (战斗屏三区几何与棋盘格边长——分辨率档位组) +# 判据出处: design/gdd/systems/表现与支撑/HUD框架.md「验收标准」以下判据逐条可测 以下判据逐条可测(战斗屏三区几何与棋盘格边长——分辨率档位组) await get_tree().process_frame var main: Node = load("res://presentation/main.tscn").instantiate() add_child(main) @@ -59,7 +59,7 @@ func _ready() -> void: # 一份不变量断言,逐档代入——代码量与档数无关 func _check_one(label: String, main: Node) -> void: -# 判据出处: design/gdd/systems/表现与支撑/HUD框架.md:264 (单档几何断言组) +# 判据出处: design/gdd/systems/表现与支撑/HUD框架.md「验收标准」以下判据逐条可测 以下判据逐条可测(单档几何断言组) var vr: Rect2 = get_viewport().get_visible_rect() if vr.size != Vector2(VIEWPORTS[0]["size"]) and vr.size.y < 1.0: _problems.append("[%s] 逻辑视口退化 %s" % [label, vr.size]) diff --git a/game/probe/level_map_shot_probe.gd b/game/probe/level_map_shot_probe.gd index f637f333..3630ad57 100644 --- a/game/probe/level_map_shot_probe.gd +++ b/game/probe/level_map_shot_probe.gd @@ -11,7 +11,7 @@ extends Node const SEED_L3 := 910212 # 深图固定种子(与 level_map_viewport_probe 同源——图确定性承载) func _ready() -> void: -# 判据出处: design/engineering/test-conventions.md:84 (关卡画面截图取证——载入守卫组) +# 判据出处: design/engineering/test-conventions.md「7. 判定可靠性优先于覆盖率」跑一遍没崩 跑一遍没崩(关卡画面截图取证——载入守卫组) var args := OS.get_cmdline_user_args() var out_dir := args[0] if args.size() > 0 else "user://" await get_tree().process_frame @@ -45,7 +45,7 @@ func _settle() -> void: func _make_runner(entry: bool, node_id: int): -# 判据出处: design/engineering/test-conventions.md:84 (判定上报通道——验证函数组) +# 判据出处: design/engineering/test-conventions.md「7. 判定可靠性优先于覆盖率」跑一遍没崩 跑一遍没崩(判定上报通道——验证函数组) var rng = load("res://core/rng_service.gd").new() rng.new_adventure(SEED_L3) var runner = load("res://core/level_runner.gd").new(get_node("/root/ConfigDB"), rng) @@ -85,7 +85,7 @@ func _deepest_with_outs(screen, runner) -> int: func _shot(out_dir: String, fname: String) -> void: -# 判据出处: design/engineering/test-conventions.md:84 (判定上报通道——验证函数组) +# 判据出处: design/engineering/test-conventions.md「7. 判定可靠性优先于覆盖率」跑一遍没崩 跑一遍没崩(判定上报通道——验证函数组) DirAccess.make_dir_recursive_absolute(out_dir) # 落盘目录自建(save_png 对缺目录静默失败——刷新链不预建) var img := get_viewport().get_texture().get_image() var err := img.save_png(out_dir.path_join(fname)) diff --git a/game/probe/level_map_viewport_probe.gd b/game/probe/level_map_viewport_probe.gd index 42118dbe..a88986e9 100644 --- a/game/probe/level_map_viewport_probe.gd +++ b/game/probe/level_map_viewport_probe.gd @@ -22,14 +22,14 @@ var _runner # 当前停点的单关 runner(open_choices 驱动随记—— func _check(desc: String, ok: bool) -> void: -# 判据出处: design/ux/level-map.md:3 (判定上报通道——验证函数组) +# 判据出处: design/ux/level-map.md「UX Spec: 关卡画面」四项设计拍板 四项设计拍板(判定上报通道——验证函数组) _checks += 1 if not ok: _problems.append(desc) func _ready() -> void: -# 判据出处: design/ux/level-map.md:3 (关卡画面视口跟随——卷轴视口组) +# 判据出处: design/ux/level-map.md「UX Spec: 关卡画面」四项设计拍板 四项设计拍板(关卡画面视口跟随——卷轴视口组) await get_tree().process_frame await get_tree().process_frame var host := Control.new() @@ -62,7 +62,7 @@ func _ready() -> void: ## R1 浅图整幅居中无裁切+画布入视口件承载(画布=视口首子件——setup 注入序) func _probe_shallow_no_crop(screen, vp) -> void: -# 判据出处: design/ux/level-map.md:3 (浅层不裁切组) +# 判据出处: design/ux/level-map.md「UX Spec: 关卡画面」四项设计拍板 四项设计拍板(浅层不裁切组) _runner = _make_runner_entry(1, SEED_L1) screen.open_choices(_cand_nodes(_runner), _runner) await get_tree().process_frame @@ -81,7 +81,7 @@ func _probe_shallow_no_crop(screen, vp) -> void: ## R5 前置+深图入口停点:锚点=入口组包围盒中心夹紧(spec :101——多入口并列取包围盒居中) func _probe_deep_entry_clamp(screen, vp) -> void: -# 判据出处: design/ux/level-map.md:3 (深层入口钳制组) +# 判据出处: design/ux/level-map.md「UX Spec: 关卡画面」四项设计拍板 四项设计拍板(深层入口钳制组) _runner = _make_runner_entry(3, SEED_L3) screen.open_choices(_cand_nodes(_runner), _runner) await get_tree().process_frame @@ -175,7 +175,7 @@ func _probe_clamp_bounds_and_columns(screen, vp) -> void: ## R6 拖拽不触发选路提交;阈值另一侧完整点击仍提交(提交语义零改动) func _probe_drag_no_submit(screen, vp) -> void: -# 判据出处: design/ux/level-map.md:3 (判定上报通道——验证函数组) +# 判据出处: design/ux/level-map.md「UX Spec: 关卡画面」四项设计拍板 四项设计拍板(判定上报通道——验证函数组) # 重建到中段可居中停点(候选=停点出边——候选节点居屏中可拖可达) var stops := _centerable_stops(screen, vp) if stops.size() < 3: @@ -214,7 +214,7 @@ func _probe_drag_no_submit(screen, vp) -> void: ## R2 停点切换后当前节点居中(视口中线投影 x=640±2——视口满屏宽即屏中线) func _probe_follow_anchor(screen, vp) -> void: -# 判据出处: design/ux/level-map.md:3 (判定上报通道——验证函数组) +# 判据出处: design/ux/level-map.md「UX Spec: 关卡画面」四项设计拍板 四项设计拍板(判定上报通道——验证函数组) var stops := _centerable_stops(screen, vp) if stops.size() < 3: _problems.append("R2 可居中停点不足(=%d)" % stops.size()) @@ -230,7 +230,7 @@ func _probe_follow_anchor(screen, vp) -> void: ## R7 平滑滚动有 tween 中间帧;减动效开=位置即达(画布坐标域判定) func _probe_smooth_scroll_reduced_motion(screen, vp) -> void: -# 判据出处: design/ux/level-map.md:3 (判定上报通道——验证函数组) +# 判据出处: design/ux/level-map.md「UX Spec: 关卡画面」四项设计拍板 四项设计拍板(判定上报通道——验证函数组) var saved_scale: float = UiKit.motion_scale UiKit.motion_scale = 1.0 var stops := _centerable_stops(screen, vp) @@ -270,7 +270,7 @@ func _probe_smooth_scroll_reduced_motion(screen, vp) -> void: ## R8 指引件可见性与几何(深图超窗——像素级判据②③) func _probe_guidance_chrome(screen, vp) -> void: -# 判据出处: design/ux/level-map.md:3 (判定上报通道——验证函数组) +# 判据出处: design/ux/level-map.md「UX Spec: 关卡画面」四项设计拍板 四项设计拍板(判定上报通道——验证函数组) var band_l: Control = vp.get_node_or_null(NodePath("FadeL")) var band_r: Control = vp.get_node_or_null(NodePath("FadeR")) var chip: Control = vp.get_node_or_null(NodePath("PanHint")) @@ -302,7 +302,7 @@ func _probe_shallow_guidance_hidden(screen, vp) -> void: ## 入口停点 runner(defer_entry——选路态挂起、候选=入口节点) func _make_runner_entry(level_index: int, seed_val: int): -# 判据出处: design/ux/level-map.md:3 (判定上报通道——验证函数组) +# 判据出处: design/ux/level-map.md「UX Spec: 关卡画面」四项设计拍板 四项设计拍板(判定上报通道——验证函数组) var rng = load("res://core/rng_service.gd").new() rng.new_adventure(seed_val) var runner = load("res://core/level_runner.gd").new(get_node("/root/ConfigDB"), rng) @@ -313,7 +313,7 @@ func _make_runner_entry(level_index: int, seed_val: int): ## 中段停点 runner(断点续玩重建——图由种子+参数档重生成同图,零 RNG 消耗) func _make_runner_at_stop(level_index: int, seed_val: int, node_id: int): -# 判据出处: design/ux/level-map.md:3 (判定上报通道——验证函数组) +# 判据出处: design/ux/level-map.md「UX Spec: 关卡画面」四项设计拍板 四项设计拍板(判定上报通道——验证函数组) var rng = load("res://core/rng_service.gd").new() rng.new_adventure(seed_val) var runner = load("res://core/level_runner.gd").new(get_node("/root/ConfigDB"), rng) @@ -388,7 +388,7 @@ func _extreme_node(pos: Dictionary, nodes: Array, first: bool) -> Dictionary: func _finish() -> void: -# 判据出处: design/ux/level-map.md:3 (判定上报通道——验证函数组) +# 判据出处: design/ux/level-map.md「UX Spec: 关卡画面」四项设计拍板 四项设计拍板(判定上报通道——验证函数组) if _checks == 0: _problems.append("零断言执行(断言数下限闸——三硬闸③)") if _problems.is_empty(): diff --git a/game/probe/probe_coverage_recorder.gd b/game/probe/probe_coverage_recorder.gd index e0b853ac..334dc808 100644 --- a/game/probe/probe_coverage_recorder.gd +++ b/game/probe/probe_coverage_recorder.gd @@ -234,7 +234,7 @@ func _seen_into(node: Node, keys: Array[String]) -> void: # ---- 落盘(JSONP 式 .js——file:// 页面