--- name: search-performance-optimization description: 在战斗语义已证明正确后,审计或修改 CombatSolver 的候选展开、Beam 保路、终局排序、评分、剪枝、Pareto、转置、预算、分配、No-GC 或 Steam 实机卡顿。 --- # CombatSolver 搜索质量与性能优化 ## 适用边界 先证明同一起点、同一动作的 actual/simulated 状态一致。存在根快照、语义或续用偏差时转 `combat-semantic-change`,不要调搜索掩盖。 读取 `docs/ARCHITECTURE.md` 的 Search 章节。当前搜索职责已拆开: - `Expansion` 产生候选; - `ParallelExpansion` 准备并物化原始候选;`AdmittedExpansion` 用固定 lane 调度已准入父节点内的动作/选择/药水作业,`PrimaryChoiceReplay` 保存原预算必经的首层回放,`EndTurnChoiceReplay` 将同一保证用于回合尾部的首层挂起选择;嵌套预算及实例补充由唯一续接原序消费,再按输入顺序提交; - `StandPatJobs` 复用当前 lane 评估保路必经的 EndTurn 探针,原序缓存与选择仍由 coordinator 完成; - `RetentionJobs` 复用已排空的 lane 计算保路只读元数据,按索引交回独占结果,观察请求及计数仍串行写入; - `StateEvaluation` 计算快照、威胁和评分特征; - `PredictionCoverage` 可以在原四字段去重后物化gap,但仍须逐项执行原补偿判定,并保持SourceId/Method稳定排序及同键先遇到者;不能把本地去重扩展成跨历史/分支回调缓存。 - `BeamRetentionPolicy` 决定中间候选保留; - `FinalPlanOrdering` 决定终局路线; - 最终续用戳由 `Terminal` 冻结选中路线的动作索引/回合边界,在既有完整标注回放的动作作用域退出后捕获。保持 EndTurn/强制结束、非死非胜且无边界、有该回合后续动作的原资格,准备根只回放一次已选 setup。只保存纯值,不 Fork 带遗物记录器的模拟器;结尾核对全部边界与最终状态。旧独立前缀回放只作测试 oracle;减少的物理 replay/setup transition 计数须如实报告,不伪加计数,不把长路线收尾收益外推为整搜提速。 - `SearchRunContext` 拥有单次运行指标、转置和缓存; - 就绪负缓存实验已因正式对照两对更慢而撤回,生产不含该缓存。它只省去同父状态未变化时的重复选择数组扫描;coordinator派发/接收时失效,不减少父槽轮询或邮箱次数。诊断命中时重扫可验证失效覆盖,不能把数组扫描减少率当作整搜提速。 - `CombatBeamSolver.Transpositions` 保持原六维支配关系与接纳顺序;单标签内联,多标签才分配List,重新缩为单标签时释放容器。只改变存储形态,不能清空仍有消费者的判重表来追求GC指标。 - `CombatSearchCoordinator` 组织主搜索与药水反事实。 不要把所有问题重新塞回 `Solve` 或用一个总分同时承担保路与终局政策。 ## 1. 建立可比较基线 固定同一源码版本、快照、预设和测试模式,记录: - phase / boundary、searched turns / shuffles; - expanded、transitions、choice branches; - dominance / transposition / repeatable pruned; - elapsed、allocated bytes、bytes/transition; - GC 次数、总/最大暂停、最大帧和 `>50ms` 帧; - 战损、药水、结束回合、动作序列和 unexpected replans。 快速内环只保留目标质量和一个不可退化哨兵。固定长线性能基线只在最终候选、准备给出性能数字或用户明确要求完整门禁时运行;当前稳定场景从 `docs/TEST_MATRIX.md` 选择,不把历史数字硬编码成永久阈值。 路线质量的首要基线是同一起点、同牌序与 RNG 下的整场战损。回合数、击杀速度和展开深度只作次级信息,除非用户明确把它们设为目标;不得用更少回合替代更低战损宣称优化。 `-VerifyIncrementalSearch`(PowerShell)/ `--verify-incremental-search`(Bash)会逐转移执行完整回放,只用于正确性,不能与性能门槛组合,也不能引用其时间或分配作为生产性能。 正常搜索使用单一 `SearchPolicySnapshot.Profile`,不再有 Short/Deep 阶段或检查点;进度只表达搜索工作阶段。测试用 `FixedBudget` 与显式小节点/时间预算,统计请求总工作量与总耗时。历史 Short/Deep 日志只能按其原实现解释,不可当成当前阶段或固定工作量字段。 ## 2. 判断瓶颈所在职责 - **预算不足**:更高预算找到更好合法路线,低预算有明确时间/节点边界。 - **展开截断**:目标动作或选牌未进入 frontier,检查 `Expansion` 和单节点分支预算。 - **中间候选丢失**:候选出现后被状态去重、Beam 通道、配额、Pareto 或转置淘汰,检查 `BeamRetentionPolicy` / `Retention`。 - **终局政策**:完整候选存活但未被选择,检查 `SearchFeatures` 与 `FinalPlanOrdering`。 - **模拟成本**:质量稳定,但 fork/action/round/snapshot/fingerprint 阶段过重。 - **GC / 主线程卡顿**:分别检查 No-GC 是否保持、堆分区、其他 Mod 分配、worker yield 和主线程回调。 先定位候选在哪一层消失,再修改该层。终局政策问题不能通过提高 Beam 分数偷偷解决。 可选 `SearchPathObserver` 只提供纯值诊断:状态键用于便宜过滤,完整动作/选择路线和政策标签分别匹配;TT 接受不等于动作准入,保留不等于实际展开。Prune 比较完整仲裁后的最终集合,回合注释允许 clone 与政策标签变化;不能把父节点开始展开当作全部出边已枚举,也不能把同状态不同历史当作原路线仍然存活。初始 Start 选牌枚举与固定前缀逐步观察不在当前入口覆盖内。 需要解释首次裁剪时,可显式启用命中状态所在外层 Prune 的整池观察:未去重输入、真实 RankBest 去重排序/必保/路由/选中位置,以及全部后续仲裁后的最终集合共用边界编号。索引从0开始;路由位置进入 quota 不等于最终必保,option leader 也可能被路由上限阻挡。父排名在原 AssignRetentionRanks 之前记录;估值诊断只复制该节点已有快照中的标量,不重算评分。真实局部选择结果直接复制,不为诊断重跑选择器或对内层 RankBest 扩大采样。 同战斗状态和同转置标签不保证保留特征或循环/有序操作调度历史相同。若原动作排列被合并,先追踪实际保留代表;测试侧严格回放“实际观察前缀 + 已知后缀”可以证明战斗合法性,但不能代替真实搜索中的生成、准入及最终保留证据。 调整普通同分截线前,区分原排序、必保置换后的实际普通截线与最终药水仲裁。组内战术排序须核对当前回合和完整政策标签;若承诺不改各标签席数,应把同族成员写回其原位置,不能按族拼接或跨族全排序。静态候选池选中目标只证明局部选择,仍须检验实际后缀是否继续存活及目标质量。 `BaseScoreTacticalTies` 单进展值组战术细化实验默认关闭,显式开启也只作用于基础分精炼成员;广泛作用于普通/能力成员曾让独立根搜索到上百回合并超时,不能把局部同分置换当作免费改进。保留必保/路由位置与药水席数,复核完整协调器、训练外根及请求总展开/转移;最终质量由原比较器决定。 ## 3. 保路与终局规则 - 普通、精英和首领均不再设置固定累计卖血门槛,也不以开战HP减一限制跨回合累计卖血;回血后的可生存路线仍必须可以参与搜索。卖血统计/排序与真实死亡判断各自保留,不恢复旧5/10/15门槛或超额候选配额。 - 主结果战损下界只在根牌组、遗物、Power、药水与扩展来源落入 `StrategicHpRecoveryBound` 已核对的无治疗封闭集合时收紧;固定战后遗物回血仍计入。未知来源、治疗牌、生成牌、可重复回血及药水沿用完整缺血余量。精神过载在下个玩家回合开始施加灾厄,灾厄致死只在该玩家回合结束结算;不能将当前灾厄值当作提前损血或死亡下界。 - 组合回复证书逐来源准入并锁定原生审计版本;初始所有牌堆、待返回牌、永久牌组及全局监听前缀独立检查,未知初始来源不能因离场重新认证。根只冻结资格,分支重新计算有效再生和合法剩余剂量;禁药与额度耗尽保留已生效再生。Smart 节血界只消费完整合规无药胜利及无保命资源消耗的基线,通过现有请求传给精确用药层和开局后续搜索;不得改评分或跳过审核。未知分支保持原搜索,成长、遗物目标、强制用药与资源追回目标不能使用该特化。 2026-10-03 用户追加的原版已知来源策略由 `KnownSources` 单独实现:随机炼药尚未生成时不分配回血余量;分支实际持有的回血药水、已有再生、固定战后回血继续计入,时候未到、狂宴、可重复遗物回血及保命来源继续保留完整余量。该策略不是随机生成下的严格语义证书,不更改旧证书的证明口径。共用 Retention 及宽度/能力成员的外部胜利界准入均消费根冻结的策略资格,不只作用于首个成员;不共享可变战斗状态、转置或前沿。 用户随后明确要求五角色、全部原版怪物:当前持有的修书刀保留,未持有时不给回血余量。零 HP 额度遗物目标使用 `CanUseStrictHpRelicBound(root, policy)` 的共同门槛,不按角色或遭遇特化;无有效卡牌成长、所有遗物额度0时只剪严格较差HP,等血量的后续回合保留。正额度目标继续按原收益政策保路。开局及后续组合成员可以消费已有纯值界,不能因此新增成员预算或跨成员共享可变状态。已知来源策略资格不扩大主搜之前的计划搜索资格:未认证根的四个前置计划曾额外耗时且没有取得胜利,使储君女王从胜利退化为未完成路线;仅保留原闭包认证根的提前计划安排,其他原版根沿原阶段执行计划搜索。 - 多样性用有上限的显式通道:防守、进攻、能力铺垫、资源、控制、药水状态、集火、复活窗口、破坏性选择等。 - 只有真正独立的目标进入全局 Pareto;增加维度前比较支配剪枝、节点与分配。 - 药水/无药配额替换候选时保护已标记代表;最终药水价值仍由反事实与 `FinalPlanOrdering` 决定。 - 保牌/保钱策略在存活获胜前提下先比较未追回资源,再比较战损、成长与药水;候选展示、终局保路和跨搜索审计保持一致。未追回资源时不能按纯 HP 早停,HP-only incumbent 不适用于此目标。放走不应用强制追回排序;保策略允许为追回资源增加战损和用药,但继续遵守显式药水保护。 - 持续能力、未来资源和延迟伤害可帮助中间保路;终局比较实际胜负、战损、药水、卖血和敌方状态。 - 成长策略由主线程冻结每次成功收益的 HP 额度。完整胜利后比较扣除额度的战略战损,同分优先已实现成长再比较回合;零额度也优先免费收益。有实际成长目标时不可使用纯 HP 的早停或 incumbent 下界;有限击杀来源只在冻结的收益目标已经兑现后允许战损早停,混合/第三方来源继续成长搜索。早停还必须满足必要用药数量,不能用多药零损抢先结束仍有更少药可能的搜索;只有本场持有对应卡牌才算有目标,保存非零额度本身不算。默认开启的战损目标早停在合法完整胜利候选提交时触发,排空当前父节点/并行批次后收尾,补充搜索同样检查;增量回放须核对收益次数和额度,Pareto 不得以较少收益支配较多收益。 - 通用上下文可按单敌/多敌、普通/Boss 调整;不要按具体 encounter 或单卡硬编码路线。 - 纯启发式特征不进入战斗状态键或 `ContinuationStamp`。 ## 4. 性能所有权 - 转置表的百万上限统计两个字典的条目数,不是标签数或字节数。触顶和峰值属于单次 SearchRunContext,标签分布在搜索结束采集;比较请求时保留各通道数据,不把顺序运行通道的标签总和当作同时驻留峰值。 - 生成选项的最新历史查询沿现有尾表/前缀段反向扫描,返回与原正向 LastOrDefault 相同的事件实例;来源仍按 Original/Preview 引用匹配,不能限制为当前动作或换成同名卡牌。查询不存跨调用结果,未匹配仍为全历史扫描;验证父子Fork后分别追加、空来源及重复生成。内存自适应并行批次数单列为调度指标,实际工作量与完整路线仍严格对账。 - `StrategicEffectContext.Build` 的消耗关键字只按实际需求读取,可空布尔缓存严格限于单张牌的当前只读循环体;下次Build必须重新读。保留完整 `Keywords` 来源,不能换成本地关键字;技能因效果消耗与牌自身消耗继续区分,第三方类型的生成器旁路不变。不要把这个局部复用扩展到动作、快照或Fork之间。 - 淘汰快照按 `SimulationSnapshot` 引用身份保留,不按 SearchNode 身份或值相等判断;多个节点可共享同一快照。`ReleaseDroppedSnapshots` 的局部集合只替代成员查询,不能改变释放调用顺序、次数或时点,不能跨调用持有模拟器图。小池保持原扫描;阈值不是全局最优承诺。 - `SortByBeamRank` 只在单次排序内预计算分数,临时列表保持节点引用和原 `CompareBeamRankOrder`,不缓存可变父排名、不跨排序复用、不增加长期节点字段。公式输入在排序期间必须冻结;修改表示或排序入口时核对完整同分顺序,不能用 top-k 集合相同代替。额外临时分配与实际搜索耗时一并报告。 - 遗物优先级只作用于既有 HP/额度轴后的达标偏好,默认 1;3 高于所有低档内置目标之和。新增半血目标时,阈值内/外的目标掩码必须参与原 Pareto,不能让高生命未达标状态支配低生命已达标状态。MeatOnTheBone 仅在用户开启目标且完整获胜时补入实际回血与原单调回血的差额,并沿首领 HP 价值折算,禁止再向实际回血或生命值重复加一次。该差额单独存入 HealingHpCredit,仅抵扣净战损,不作为同分成长奖励;带骨肉不附带额外额度或优先级奖励。比较其他目标一致的路线间收益,不能要求最终 HP 超过搜索根 HP。 - 遗物卡数只针对本场实际持有且总/单项开关开启的跨战斗计数;每项达标额度只记一次,范围覆盖全周期不创建目标。早停要求完整胜利中的所有计数目标已满足,并保留原实际扣血、成长、偷窃与用药条件,不能因开关开启而一律禁用达标早停。保路 Pareto 比较达标掩码的包含关系,不能只比较总数。后续动作探针须保留完整前缀父链,增量回放不能从空历史验证非空前缀状态。 - `BeamRetentionPolicy.RoutingChoiceScratch` 只复用空字典桶;每次 `RankBest` 的 `RoutingChoiceNodes` 独占候选列表和五项代表,按原比较规则聚合,归还时清空引用,不跨调用缓存组。组填满后用原 `Max/Min` 冻结最高 Beam 分、最高父分和最低父排名;只在本次 routing block 中使用,全部消费早于 `AssignRetentionRanks`,下一次调用重新建立。不得把该组统计扩展成单节点父链或跨调用排名缓存;新统计必须证明有效期并对比包括 deferred-round 诊断在内的相关非时序指标。 - `SearchRunContext` 是单次运行可变指标、转置和缓存的所有者;不要把这些字段退回 solver 入口或静态全局。 - 请求工作归因复用 `SearchRequestWorkTotals` 原总账本:经续搜调度器的 solver 用 `ContinuationPurpose` 标记,主搜、宽度精炼及直接审计/侦察成员用 `DirectSearchPurpose` 标记,仍未标记的直接成员记 `UnattributedDirect`,协调器开销另列。各分项之和须与原展开、转移和选择总计一致;阶段名不能替代候选丢失证据,旧超时包没有进度快照时保持未归因。 - 混沌药生成链成员只在根药水确有生成源、原路线尚有可改善战损且请求账本有余量时运行。候选来自已选路线早期前缀及合法进攻跟进,生成药的免费身份从分支状态读取;最多两条前缀,每条共享请求节点/时间,完整结果由既有用药政策取优。强制用药按原政策验证,不以包 ID 或预定卡牌顺序提名。 - 无完整胜利追加搜索位于请求级、主搜索与药水审计之后,消耗请求剩余时间。每轮分配/转移采样从该轮开始计;采用或应用结果直接交还调用者。饱和判断比较上一轮全部搜索维度,预设节点调整与动态恢复倍数分别记录。 - 并行 worker 只能拥有 lane-local 模拟、缓存、节流和原始候选;transposition、dominance、fallback、预算与最终接收顺序仍由 coordinator 独占。固定 lane 应在一次 `Solve` 内复用,禁止回到每父节点 `Task.Run` / 新建 solver。 - 外层最多预约 `2×DOP` 父节点,已准入作业内同时模拟最多 DOP;自然 singleton 也使用同一调度器。准备动作表后,每父节点独立 Fork gate 串行生成 seed,lane 在 gate 外独占模拟。动态选择预算及 occurrence collector 属于一条完整动作链,不并发消费同一个预算。药水/目标是独立作业,初始动作/药水均已派发后可独立计算 EndTurn,仍使用同父 Fork gate,结果与基线值归私有批次;全部卡牌/选择/药水及 EndTurn 都完成后才按原边界移交结果并发布父节点 stand-pat 基线。coordinator 归并 worker 指标后才能复用 lane,按动作/药水原序聚合,只提交完成父节点的连续前缀。内部不能新准入父节点或做 GC checkpoint;父节点高水位预约覆盖所有在途结果,数量界不当作硬字节界。冷启动按每父节点64 MiB再乘1.5预约;完整观测后保留整次搜索最大实测父分配的1.5倍,并在每批另加96 MiB突发余量。不得在新深度重置高水位、删除整批突发余量,或把预测说成未知分配的硬保证。纯串行后备仍按原有单父节点冷下限/实测高水位预约,不叠加并行窗口的整批余量。异常停止派发、排空全部 lane 后才释放 probe/batch/root;高分支场景必须同时看峰值图和分配。 - 保路元数据并行必须冻结本次候选、父排名、已选集合和 lease 账本,逐索引或逐组独占写回;分组与最终拼接不得按完成次序进行。观察请求先收集、再按原组序应用,不能让 worker 修改共享统计或保留账本。复用已经排空的固定 lane,不使用未限并发的 `Parallel.For`;取消和错误也须等待所有已派发作业,完整记入其分配并传播原 token/异常。合同覆盖双 lane、逐槽一次写入、失败后复用和实际 NoGC 回收边界。 - 待命探针并行只覆盖原保路会访问的未缓存状态,保留首次原代表;不扩大候选集合。固定代表可按探针独占分配高水位及 Runtime 剩余内存分批,每批排空后才通过注入入口回收;非探针元数据按已排空的全局排名/探针及资源、开局、有序变异保路完成边界分段观测与预约,不在CycleRegion仲裁事务中回收,保留每输入高水位及原安全系数;不能用整段元数据或整组瞬时模拟之和预约一个不可分割区间。剪枝内回收保留已用作去重依据的 StandPatCache,离开该作用域才恢复清理。复用同一固定 lane,coordinator 独占缓存,worker 只交出标量;临时快照在发布前释放,失败和取消必须排空。最终固定节点合同同时覆盖 DOP1/DOP2、在途取消/失败和原根复用,普通单线程小预算合同不能代替这一边界。 - 只有容器进入 `SearchRunContext` 的有界空闲池;每个发布批次必须持有独立 lease,归还前清空引用,旧 Dispose 不得触碰后来租户。不得池化 simulator/model。 - 首层回放并行必须先证明原动态预算必定覆盖这些物理回放:N≥2 且语义最终额度和回放额度都≥N、选择非空时,原 ceil 租约递推保证每个兄弟的第一次回放必经。frontier 只暂存这 N 次结果,原序续接消费逻辑额度;嵌套选择与实例补充不并发。不能把各兄弟预先固定为平均总配额,也不能在预算不足时猜测准入;合同覆盖饱和、无效、混合消耗与512上限。 - Snapshot 临时牌列表只由当前 `_run` / lane 租用,维持 Discard → Draw → Hand 拼接顺序和原稳定洗牌。归还清空引用,只留一个容量不超过 4096 的列表;租用代次防止复制的旧 lease 清空新租户,禁止把列表存入返回快照或策略上下文。 - GC 生命周期计数由 Runtime 在准入 Gate 内冻结。普通 GC 的共享进程窗口不得称为独占请求归因;总暂停、observed max 与 trace max 必须区分。Smart 预测只决定可选层间回收,不能改层预算或候选策略。 - RitsuLib 0.6.0 已拥有 BaseLib 目标类型的外部登记查询、ConditionalWeakTable 弱所有权和动态程序集旁路。CombatSolver 不再修补该桥的私有闭包或另建缺失缓存;性能工作不得恢复这组重复补丁,目标类型语义继续走框架公开入口。 - Hook 分发优化只省略已核对为原版默认空操作的回调,不能删除原生/领域监听成员。`MirroredHookListenerFilter` 的布局只含 Type/位图,按原位置对应当前分支模型;同根有界共享表必须逐项核对完整类型顺序,哈希碰撞或并发替换只允许降低命中率。表不持有 Model,普通监听失效清空派生视图,根结束后共享表可回收。每个新根重新检查基方法和原生关键字 Hook 补丁,第三方/动态类型与不透明 CardModifier 旁路;新回调同步两端位图门禁。原生关键字调用只能在确认全体接收者为空操作时省略。记录缓存命中/碰撞/旁路,根累计指标不能把主搜与恢复相加。 - 监听前段只含阵容/遗物/药水/根 Power,卡牌/球变化不得修改已发布前段;阵容/药水变化仍完整失效。有效 Power 插入缺少前段锚点时回退原完整列表,不透明 CardModifier 也保持完整列表及追加器上下文。只有不可变已发布段才能冻结拼接长度;Fork 经同一上下文重映射,复用后段不得保留父分支可变模型。有效/活动前段及 Power 投影只在成功分段时跨卡牌/球变化保留;Power、阵容、药水失效必须同时清空,Fork 也要重映射已失去完整后段的保留前段。测试覆盖无前段锚点、卡牌变化后前段复用和 Fork 引用。 - worker 阶段 ticks 来自 `Stopwatch`,合并后是各段经过时间之和,包含被抢占、锁等待与 GC 暂停,既不是实际 CPU 时间,也不是墙钟占比。实际 CPU 使用 perf on-CPU 样本或线程调度运行时间;同时记录 `parallel_waves`、`parallel_work_items`、`parallel_max_concurrency` 和平均用核数,避免只凭峰值并发宣称已充分并行。 - BaseLib `3.4.5` 的克隆扩展会以非原子的“先查后加”访问全局弱表。并行搜索必须保留 `BaseLibCloneConcurrencyPatch` 对原版 `MutableClone` 第三方扩展段的窄串行边界;不要删除该边界,也不要把它扩大到候选生成、模拟、剪枝或提交阶段。 - 原生 `PowerModel.GetTypeForAmount` 的枚举装箱优化只能替换精确匹配的两段同 int 枚举比较;保留所有虚 getter、decimal 判断、标签与异常区域,内部控制流或未知 IL 旁路。生产 transpiler 必须以真实游戏方法核对输出、getter 次数/顺序、未定义枚举值与分配;不能用跳过 getter 的类型缓存代替。 - 游戏 `0.111.0` 的 `LocManager.SmartFormat` 复用同一个 SmartFormat 实例及对象池,不支持并发调用。`PowerDynamicVarWarmup` 必须在主线程根捕获时物化规范 Power 与当前战斗 Power 的显示变量;`PowerDynamicVarMaterializationGuardPatch` 保证 worker 不再惰性创建 Power 显示变量。命中 guard 时补齐主线程物化边界,不给全局格式化器加锁,也不在 worker 内提供默认文本。`LocManager.SmartFormat` 本身含异常过滤器,禁止直接用 Harmony 改写。 - Runtime 拥有 `SearchGcPolicy`,Search 只通过 `SearchFramePressureSignal` / `SearchWorkPacer` 消费节流信号。 - 层间预测不能要求整层必须容纳于单一区域。预测超过新区域容量或区域新分配很少时,使用原每批内存准入,不能反复重置刚完成回收的区域。普通 GC 的自动回收请求后台收集;需要重建 NoGC 的排空检查点直接请求一次压缩完整回收,确认新完成信息和释放后的弱引用哨兵后重建区域。手动释放继续使用自己的完整回收入口。实机曾证明按高碎片比例自动压缩会造成数秒停顿;生命周期合同只证明完成与所有权,可见暂停和平台性能另行取证。保持确认、取消与引用释放的所有权。 - 手动释放先通过完整、阻塞、压缩的 `GCCollectionMode.Aggressive` 归还游戏空闲堆页面,再按用户明确要求调用管理员辅助程序清空全系统进程工作集与待机列表,保留系统和其他进程清理能力。工作集移出后的低占用不能当作堆已释放,恢复执行或下次 GC 会重新载入页面。核对 private/committed 与工作集各自的变化;`manual-release` 真实 CLR 合同及储君生成路线部署合同只覆盖游戏进程回收,不覆盖管理员系统清理,也不证明全部内存耗尽已解决。 - 动态变量空元数据优化只针对已核对 null 默认值的 BaseLib 提示/升级字段和 Ritsu 提示工厂复制入口,在模拟隔离域使用不创建条目的查询;保留非空值、父子隔离及 live 路径,不改通用字段工厂或清空全局表。以真实 Clone 验证空值基线、自定义提示和升级值跨两代传播。 - 原版 NodePool 信号清理只释放自己取得的 Array/Dictionary/Variant 与新转换的名称包装,不释放节点或持久 Callable 目标。修改该补偿时分别验证 NCard/NGridCardHolder 的真实泛型入口、入站/出站/递归/离树条件及包装登记数;不能把登记无增长当作全部旧战斗对象已释放。 - 搜索内回收只等待自己发起的收集,不加入要求该搜索退出的 deferred 完成链。后台 GC 请求不等于回收完成:核对最新已完成 Gen2 与释放后哨兵,取消不能提前交还所有权,超时/异常必须排空未确认请求。手动完成、引用释放 epoch 与搜索取消各有独立语义;请求后台模式与 CLR 实际 Concurrent 结果分开记录,生命周期合同不当作暂停收益证据。 - 优先避免无价值候选、Fork 和快照产生;No-GC 区内释放引用不会返还预算。 - 组合补搜入口消费基线完成情况及原节点、时间余量;内存由成员执行期间的逐批预约和 Runtime 检查点处理。成员可跨多个回收区域完成,累计分配量用于成本诊断。新增成员的工作会影响后续审计余量,必须比较完整请求的质量与实际总成本。 - 区分 transitions 增长与 bytes/transition 增长,用阶段指标定位实际热点。 - No-GC 同时观察配置预算、SOH/LOH、是否保持到搜索退出和首次长帧时的 expanded。 - 准入必须有下限:区域只吸收本次搜索相当一部分分配时才值得进入。`TryStartNoGcRegionWithSizeFallback` 是对半砍到 `MinimumNoGcRegionBudgetBytes`,任何 `Started` 都会被建立,因此**只在尺寸回退循环之前捕获 `Capped`**(该标志等价于「机器给不出配置预算」)并在系统余量缩水到配置的一半以下时拒绝进入、改走默认 GC。平台 SOH 上限造成的缩水是合法机制,不能因此取消区域。拒绝后必须确认分配限额被释放(`RemainingBytes == long.MaxValue`),否则检查点仍会为不存在的区域付拆除成本。检查用 `tools/testing/checks/CombatSolver.GcPolicyChecks -- admission`,它直接编译生产 `SearchGcPolicy.cs`,不需要游戏进程。 - 修 GC 策略前先确认保留集是否有界:`SearchRunContext` 的转置、StandPat、Coverage、ThreatProjection 等结构无裁剪、无上限,托管堆 52% 碎片时非紧凑回收中位只能拿回 0 MiB。**这类问题改 GC 策略治不了**,把内存从「输出」变成「输入」要落到 `BeamRetentionPolicy` 的容量维度,属语义改动,需完整等价性门禁。不要用准入/回收的复杂度去补保留集的无界。 - 收益小且扩大语义验证面的微优化保留简单实现。 - **按类型归因时必须取该类型的调用栈,不能从类型名猜调用点。** 分配 trace 只给出「哪个类型分配了多少」;`Func` 这类泛型名会误导人去找同名形态的代码。先对目标类型取栈定位文件与行号,再改;改完必须用**同一类型**的前后字节数验证是否真的下降(总分配可能被其它来源淹没而看不出变化)。凭类型名推断曾把 `PredictedCard` 谓词当成 `CardPile` 谓词,改错文件:213 行改动换来总分配 +0.069%,只能回退。仓库自带的 `tools/performance/GcTraceAnalysis` 每类型条目不带栈,需要加大 `--top` 后在 `topSearchStacks` 里按类型过滤,或按类别条目交叉核对。 - 反编译核对游戏类型用 `.local/decompiled-tmp/sts2/`(按命名空间分目录);`ilspycmd` 在本机安装失败(NuGet 包缺 `DotnetToolSettings.xml`),不要重复尝试。核对该目录时要用「实测调用栈里的方法链」交叉验证版本一致性。 ## 5. 实验与验证 将工作移到精确转置准入之后时,须证明被延后的计算不参与原始节点的状态键、标签、租约和诊断。卡牌战术分类可以延后到普通分支通过之后,但有序变异与循环延后准入继续走原路径。`EquivalenceProbe` 的自然AB/BA指纹观察只能定位机会,不能作为跨状态交换性证书;开启观测器时不作性能结论。 跨跑局、SL 后仍持续的实机卡顿可使用 `docs/performance/long-session-recording.md` 的显式本地录制。核对进程会话完整性、分段空窗、EventPipe 丢事件与采集自身开销;采样线程时间不当作 CPU 占比,弱引用存活不当作 GC root 证据。诊断改动和行为修复分开取证,节点重建必须继续原进程会话。 确定 GC 发起者时读取 GCTriggered 的关联栈,不用 GCStart 无栈推断未采集;EventPipe stack blocks 不等于独立 ClrStackWalk 事件。句柄窗口只覆盖部分时间且栈覆盖不完整,明确报告覆盖率,不将跨窗创建/销毁差值当成全程泄漏量。Collector complete 必须与解析完整性分开。 有序选择谱系和持久身份变异分类不是同一个入口;扩展谱系前核对辅助判定的全部调用方,不能顺带改变动作分支配额、原路由或后续选项来源族。静态 builder 合同只证明值传播与边界清空,不证明真实碰撞、付费准入或完整路线改善。 补上某个生成选项的保留后,继续核对下一实际选择是否替换了最新路由签名;前一步实际展开不等于后一步继承同一覆盖。当前选择输出仍保存可区分的有序牌堆时,先验证其现有上下文,不因签名替换就直接引入祖先租约或额外历史额度。多敌路径观察应冻结原始敌人身份并逐敌核对根/live不变;单敌别名后缀证明不能未经扩展就用于多敌。 同一粗路由来源族可同时含刚完成选择的节点和经过多步后的后继,二者的动作数、实际战损与政策标签可能不同。针对新鲜选择缺口提名代表前,先以实际choiceNode身份区分两者;不能直接用整个来源族的最高分把待保护的新生状态再次排除。路由入口缺席也不等于最终集合完全没有该族。若规则承诺每个外层Prune最多一次,须显式隔离内层RankBest调用,不能靠观察器是否开启控制生产行为。 下一断点的完整路由签名可能仍与前一步完全相同;应检查同父同动作不同目标是否已经有代表存活,以及实际/投影生命和完整政策差异。相同战术值不表示相同目标状态,不因准确路线落选就延长祖先保护。撤回实验时检查专属派生字段的所有消费者;只服务测试的区分量优先留在测试侧,删除冗余核验也须明确其诊断覆盖变化。 1. 每轮只改变一个可解释因素,失败实验立即撤回。修改前量化所选子路径的成本;缓存方案记录命中/失效/旁路,COW 记录写入比例与实际复制量,不能把整个阶段占比当作某个小容器的收益空间; 已出现同版时间漂移时,预先设计有首尾基线或交错 A/B 的测量序列,报告单样本与范围;这属于必要实验设计,不是测试通过后的安心重跑。小于已观测漂移的差异只能判为收益未建立,不能断言真实提速或回退; 微架构分析区分实际 CPU、分支失误、IPC、缓存与调度等待。记录 PMU 的事件映射和 multiplex 比例;通用 cache-misses 不自动等同 LLC/DRAM,采样落点可能有 skid。SIMD、去分支或内联必须核对 JIT 汇编与数据依赖,不凭 C# 行数判断; 2. 快速内环用固定短预算或固定小节点工作量,只跑目标首轮质量;单个 unattended 请求总超时不超过 `120` 秒,并在首个 solver 结果处停止; 3. 目标改善后跑一个不可退化哨兵。药水、卖血、延迟伤害、复活和选择只挑受本次因素影响的代表,不枚举全部类型族; 4. 只有最终候选才做一次 Release 构建、结构门禁和必要的增量等价;增量数字不用于性能比较; 5. 完整自动战斗只在搜索行为确实改变且需要证明部署/复用、用户明确要求完整回归,或准备给出整场质量结论时运行;固定 `Instant / 0 秒`、零非预期重算。超时后不在同一轮扩大等待时间; 6. 固定长线性能与正常可见 Steam 会话只用于最终性能结论,不进入每次参数尝试; 7. 并行改动的最终候选固定节点工作量,至少比较 DOP1/DOP2 的动作、评分、展开、转移和全部非时序剪枝指标,并断言 DOP2 的实际最大并发不小于 2;详细诊断和增量模式继续用 DOP1; 8. 改动涉及 coverage/state 分类时运行对应 CoverageCatalog verify。 职责迁移时同步 `docs/ARCHITECTURE.md` 和结构门禁。搜索行为或指标变化同步开发笔记与测试矩阵。普通优化直接提交;版本和打包时机以 `AGENTS.md` 的活动发布批次和发布口令为准,再转 `release-gate`。 - 预测卡牌/Power 克隆的免锁路径由 `NativeModelCloneConcurrency` 核对:仅隔离域、普通原版卡牌或默认内部初始化 Power、已物化原版变量、原生克隆阶段与精确 BaseLib/Ritsu 稀疏复制补丁组合。Power 还须核对默认 InitInternalData、AbstractModel.DeepCloneFields 与 Power.DynamicVars 物化保护补丁;自定义初始化、附魔/灾厄、第三方模型或变量、未知补丁均走原锁;不得为判定路径而物化共享源变量。证据限线程当前最外层隔离域,跨域刷新,不缓存模型或分支值;原版 `MutableClone` 的 BaseLib 锁保持。合同须真实加载 BaseLib,并持锁验证并行、变量独占与跨域补丁失效。 - 选牌组合的评分仅可在单次BuildChoices的不可变组合中惰性复用,未消费评分的路径不提前计算;不跨spec、模型变化、Fork或调用缓存。组合去重预计算须保持原[start,i)语义,张数上限按该张数新增条目计数,固定多弃牌与物理实例代表规则不变。 同次多选的不可变PlanCardToken仅按PredictedCard引用复用,保留来源/候选序号;尾部实体直接定位须保持逐键最后N张的原序,选中数超过16回退原分组算法。验证须含重复引用、缺失候选、跨调用变更和大选择集合,不能以令牌相同为由再删实体分支。 - `PredictionStateStore` 的三槽计数表只保存 Type/条目数,不保存模型或 state;空 store 不创建计数对象,溢出仍使用独占字典,Fork 丢弃零计数。工厂可以重入并扩容,禁止跨工厂调用持有主字典 ref;计数更新的 ref 必须立即消费。验证覆盖溢出、清空后 Fork、父子隔离与工厂重入,不能只测常见一类状态。 - 根生成池仅缓存逐项核对的原生过滤:无色、角色攻击、非Basic/Ancient、Power及Common;保留角色/规范池/AllCards引用身份、约束、原生只读模型与自定义池回退门禁。后三类由TurnStartPowerSupport每次Power触发准备一次;回退路径GetUnlockedCards仍只调用一次,原谓词与战斗过滤仍逐次抽取执行,不能把取N次一张改成一次取N张。不得混用有放回NextItem与distinct TakeRandom,即使只取一张。候选模型只读共享,RNG与生成卡始终属当前分支;其他过滤未经核对不能获得缓存资格,合同须覆盖可变池回退调用次数与枚举语义。 - `ModifyHpLost` 的修正者输出是只读集合:空结果使用共享空数组,非空结果独占 List;四阶段顺序、过滤器和 decimal 截断后变化判定保持原样。`AfterModifyingHpLostAfterOsty` 的空通知仍先物化原监听来源,只省略空成员遍历及通知 context;非空按当前监听顺序/成员身份调用一次,不按修正者列表顺序直接派发。移除/重获、重复成员、完整状态与 RNG 必须对账。 - 威胁预测查找蜥蜴尾巴按分支遗物的原顺序选择首个未使用实例,不缓存 WasUsed,也不增加原查询没有的熔化/存活过滤条件。 - 大牌堆监听容量优化只统计当前分支的球、未移除卡牌和附魔/灾厄字段;不得在计数阶段执行Hook、第三方追加器或物化可变克隆。不透明来源保持原完整追加上下文,小牌堆不增加预扫描;不因此放宽缓存失效或共享模型。 - Ritsu空能力标签路径须返回原惰性序列引用,不去重、不枚举、不复制;空贡献结果不等于空能力集合。复用既有默认来源代次检查,合同覆盖异常延迟、贡献者顺序/空值、移除重获和晚注册;不可缓存标签值。 - 无色药水与CosmicConcoction可以复用已有根无色候选池,仍使用GetDistinct/TakeRandom的原RNG顺序、独立生成卡及升级。无模拟器预览保持原筛选;不将结果牌或RNG缓存到根,也不改变选一张与全部入手两种返回形态。 - NoGC 回退恢复只在 coordinator 已排空的提交边界执行 Runtime 探针。只可复用退出后检查点已确认完成、尚未用于失败预留的 Gen2 证据;否则等待新的已完成 Gen2。首次有完成证据可立即尝试,后续保留实际物理余量及指数退避,冷却上限为 60 秒;尝试次数跨回退段累计,成功恢复后继续保留计数,以冷却约束重试频率。恢复资格只属于 InsufficientMemory、SystemHeadroomInsufficient、SkippedAfterUnexpectedLoss。保留恢复后的区域上限,不能立刻扩回原大预留。全堆 FragmentedBytes 不构成 NoGC SOH 必能复用的容量证明。探针不得强制收集或等待 deferred 链;退出请求、scope 代次、取消和 Dispose 必须阻止旧探针复活。用户关闭、平台/尺寸不支持及主动不可分割回退保持普通 GC。合同须穿过真实 CLR 的退出/恢复和 UseDefaultGcAndContinue 主动退出入口,而非只测试状态机或分类函数。 - 按消费者省略战略上下文字段时,核对外部登记器可读取的既有字段;登记表非空保留原上下文,不因第三方未声明新需求标志就返回0。原版与第三方字段消费者分别用最小合同覆盖。 - `RoundTransition` 只在无计划选择的EndTurn初探保存无挂起事务的前缀:普通抽牌与历史补偿后为原稳定点;抽牌准备及一次性抽牌修正消费完毕、Simulator.Draw之前为洗牌选择的更早稳定点。后者只在将发生洗牌、当前worker已观察到该处产生有效选择层、且对应SourceId的玩家Power当前仍有效时预留;提示只存字符串,不持有模型。未命中保留较晚稳定点,未知非Power来源完整回放。抽牌前checkpoint保存已消费的drawCount,续接重建BeforeNextTake回调且不重复消费修正或提前触发SideTurnStart。ToolsOfTheTradePower继续立即预留抽牌后前缀。学习提示仅属worker的运行上下文,不跨搜索、不进入战斗键/候选政策;未到稳定点的选牌不得启用。原Fork事务断言保持,复制前临时关闭空cursor并在finally恢复。前缀匹配父节点引用、EndTurn回合与PlayerTurnStart选择,Knowledge选择完整回放;frontier拥有checkpoint,同父gate串行Fork,排空后释放。新增捕获计数包含额外物理Fork,DOP等价比较扣除该项后的转移Fork;完整状态/续用/历史、连续洗牌与变牌选择、延迟抽牌修正及兄弟隔离须直接对账。 - RNG 惰性物化只共享完整计数器/四段状态值的不可变快照;已有可变实例的流必须在 Fork 当时捕获,不能把原生 Rng 当成 COW 共享,因为调用方可能继续持有旧引用。只读状态键/续用/投影读取不物化源流,真正随机操作仍使用分支独占的原生实例。合同覆盖九条流的原生序列、保留引用、兄弟/多代 Fork、只读未物化与 live 不变;实际整搜分配和时间分别判断,不把未访问流比例当作整搜收益。 - 卡牌首次进场检查由 `PredictedCard.HasCheckedPowerAfflictionEntry` 按 wrapper 保存,根牌也标记已经检查;Fork继承,Clone重新检查,根身份集合仅捕获一次、只读共享。不得改成按卡名判断或把新wrapper当作旧卡已经处理。污染清除及数量变化仍在每次归一化检查。 - 跑局监听表仅在前缀与 `_rootRunHookListeners` 引用相同时省去重映射;该冻结前缀只含根牌组CardModel/Enchantment,State.Fork不会登记这些模型,StateStore.Fork仍在其后。其他前缀、战斗后缀与Power继续原重映射/失效逻辑。更改Fork顺序或模型登记范围时必须重新核对这条前提。 - 长期资源保路的均匀判定必须使用当前完整冻结候选池;空池和全池同值原本均返回空资源路线,可以在此前省去祖先排名暂存。非均匀池保持最高值并列成员原序、原RankBest与祖先/全局恢复顺序,不跨调用缓存最大值或排名;合同核对共享祖先、既有排名、完整选中身份和顺序。 - 正式手动自身选牌续执行支持当前清单中的41张原版单人卡,要求无附魔/污染、单次手动打出、空显式cursor、单层card scope、可重映射活动历史及无不透明/事务StateStore。Engine保存显式CardPlay/frame并复用唯一结算尾部;Prediction独占seed/frame/deaths和Fork锁,Search仅在同父同动作选择链或frontier内持有。普通Fork仍拒绝挂起种子;私有Fork临时移走所属pending request并运行原事务断言,全部模型/trace/play/history使用同一PredictionForkContext。再次挂起时退出全部子scope再完整回放,额外物理Fork单列fallback,不多扣逻辑transition/选择预算。旧路径不得运行捕获诊断或持有检查点;释放必须在生产者/消费者排空后完成。不保留Task/闭包,不跨父、搜索或战斗缓存。完整状态/历史/RNG、兄弟修改、原生结算、DOP、取消/异常排空与增量等价直接验证;各来源的命中和整搜收益分别报告。已生成的请求/spec必须一并捕获,不能在恢复时再次GetSpec(探寻打击会再次消耗RNG);同一个Fork context复制请求候选、生成历史中的非牌堆wrapper、CardPlay及其格挡金额/事件计数。 - 9种原版手动选牌药水共用 `PotionExecutionSupport.Prepare/Complete`;检查点在消费槽位和Use完成后、选择应用及AfterPotionUsed之前,种子仍须通过普通Fork断言。四种生成药水从检查点运行原空选择探测,使用后钩子执行完才读取候选;其他五种仍从父状态准备候选。Search的串行/并行准备共用入口,同父完整动作匹配且仅Choice可替换;frontier或串行枚举拥有检查点并在排空后释放。生成候选历史只读共享,Apply继续Clone选中牌;分支可变牌/RNG由普通Fork隔离。嵌套再次挂起从原父完整回放;额外前缀Fork与fallback分别记账,不改变transition/choice预算;worker合并和归零须包含四个药水计数。第三方药水或登记覆盖原版选择的药水不进入此特化。不保存Task或闭包。验证全部九种原生结算、完整状态/历史/RNG、消耗/后置钩子、兄弟修改及DOP/取消/异常/增量对账。 - 嵌套执行检查点保存纯数据帧与明确程序阶段/下一循环序号。所有CLR作用域退出后,核对领域事务、StateStore、活动CardPlay及延迟抽牌/生成历史的精确配对;普通Fork继续拒绝捕获/挂起/已准备种子。一次PredictionForkContext重映射状态、帧、候选、历史、CardPlay、Power来源及共享死亡集合,保留trace来源身份和抽牌深度限制;外层列表所持但已离开所有牌堆的wrapper也必须显式Fork,不能假设State已登记。未知派发必须拒绝整次捕获,继续原完整回放,不能默认缺失尾部已执行。已确认的抽牌、弃牌、Hook、重复子出牌与回合来源循环复用唯一普通执行体,恢复可以再次挂起。Search匹配同父完整动作及已消费选择前缀,只追加下一选择;选择层/frontier排空后释放全部图引用。不保存Task/闭包,不跨搜索缓存;严格增量基线禁用捕获。ExecutionChoiceCaptures/Reuses不扣选择预算,reuse替代一次原转移Fork,不能作为额外物理Fork从比较器扣除。源循环、深层选牌、DOP/取消/异常、有限预算耗尽与原生完整状态分别验证。 - `NoveltyPortfolio` 是默认关闭、可由玩家开启的实验性主搜索组合,不是新评分或状态等价关系。探索和Beam共享请求节点/时间,只共享完成结果,保留独立转置与frontier;预算上限、章节首领较小探索份额和短预算旁路由 `NoveltyPortfolioBudget` 决定。不能恢复实验中的无限OPEN或为每个成员重开总预算。默认参数和反例见 `docs/archive/strategy/bounded-novelty-search-20260916.md`。 - 新颖性在生成时冻结,类型化特征由当前影子状态提取。增量元组只能复用已完整记录且同分区的父事实,历史上限后保守旁路;不能以特征相等替代完整转置判重。满队列淘汰低优先级项后,必须等整个父批次发布完毕,再按快照身份释放,避免误释放兄弟共享快照。`Phases` 继续提供内存预约、接管与进度;无效用药边界与模拟失败严格区分。M配额由同一最近新颖祖先的全部熟悉后代共享,不在每条路径或每个父节点重置。 - 新搜索可因时间切层/JIT影响质量;同进程多变体仅作探索,最终对照使用独立进程和完整请求,比较原生开局、战损/成长/药水及请求总工作量。进程VmHWM含建局,不等于搜索独占峰值;无头结果不能外推可见帧时间。 - 循环终局探测仅在动作层的 worker 全部排空后按原序执行。只对已满足策略目标、零累计掉血/卖血、每步唯一可执行身份和目标的延续作真实回放;保留普通出牌和 EndTurn 出口,选牌/资源下降/漂移立刻停止额外探测,真实胜利可交付,达到动作额度的已验证无损前缀可加入普通 frontier 续搜;每步附加既有调度证据,中间 simulator 逐步释放。4096 动作由 SearchRequestWorkTotals 在整个请求共享,独立 Evaluate 才拥有私有额度;关闭达标早停不得支付该成本。DOP 对账排除本来分 lane 的缓存容量与调度计数,固定节点且没有早停时核对动作、评分、展开、转移和政策剪枝;有早停的分支根必须实测,不预设普遍 DOP 等价。有效格挡按当前投影吸收量及原规则可保留量计,固定保留上限复用清空执行的纯计算,不能退回裸 PlayerBlock 作正向进展。 - GC诊断故障不能跳过状态释放与完成源终结;请求/提升日志失败须撤销未派发状态,排队手动请求也要收到失败。操作异常与收尾异常同时发生时保留两者。此修复不改变上游预算、回收时机或恢复策略,修改后运行 `diagnostic-failure` 的8项真实CLR合同。 - 普通 GC 请求的常规检查点刷新系统内存限额;`UseDefaultGcAndContinue` 是不可分割提交的显式退出,完成回收后由 CLR 接管分配,后续请求重新建立独立限额。修改这两条路径时运行 `default-commit` 的真实 CLR 合同,并保留 Search 的显式退出契约断言。 - 上下文排序实验只通过显式不可变 profile 注入,默认关闭;加载和程序集校验在搜索前,内环不读文件或 live 设置。修正只影响中途排序,不能进入终局政策、状态等价或精确支配。训练只用有完整后续见证且同根同预算的候选;没有后续的被剪节点保持未知,旧 Score 尾键差异不作为政策收益标签。范围回退、正则和小幅修正都不能证明质量不降;须在训练外根和真实协调器上验收,按当前用户授权的质量门槛决定是否上线;允许少数退化时仍须单列胜负翻转、尾部损失与总体分布,不能仅用平均HP抵消失败。采集诊断不能作为性能样本。工具与首轮反例见 `tools/search/ContextualOrdering/README.md`。 - `ContinuousThreatRanking` 是独立、默认关闭的中途排序实验,只覆盖 EndTurn 后的新回合起点;实际死亡、终局或没有可执行手牌继续旧规则。不得将致死意图等同已完成死亡,但取消离散罚分也不证明更优;全部中途节点版本已有抽牌高压退化。保留原快照Score、终局和转置支配,训练外验证及协调器/性能证据完成前不得默认启用。 - 按HP目标结束追加组合必须使用现有完整目标判定及已选incumbent;保留关闭早停、成长/遗物/偷窃/强制用药条件。达标不等于无法进一步回血或更早击杀,必须量化这些次级取舍;正常完成、无风险结果才可结束,接管/取消仍走原流程。根的牌/Power/可搜索药水治疗元数据及已有再生在主线程物化后冻结,或已选路线实际回血时,保留追加审计;该提示不穷举未来生成和未声明治疗的来源,不能当作可达收益上界或入状态键。基线成员保持,实际请求总工作与每个跳过原因可观测。 - 单项 `BeamWeightPerturbation` 只允许通过不可变profile显式注入,生产为空。敏感度扰动在Beam分数内应用,不能改快照Score、终局/精确支配,也不能把同一根多次调参算成独立样本。默认与1倍扰动须保持路线和工作量;Scale范围检查不能代替训练外质量验收。Coordinator的原有base-score成员旁路,成员实验收益须复核完整请求。 - `OffensiveRefinementPortfolio` 实验只替换默认列表的宽精炼成员;主搜/普通窄成员保持,显式宽度配置不改。进攻项仅由该成员profile注入,不能泄漏到后续base/band或能力前缀;共享预算/准入/最终整条选优保持,身份进入运行与跳过诊断。旧选择器的特征没有该成员类型,不能让旧模型裁决它。必须查找宽成员独有胜路及新成员损失,不能从保留主搜推导整个旧组合不退化。 - `BoundedOffensiveRefinementPortfolio` 与替换实验互斥:保留原列表及预算,追加成员最多消费此前组合实际展开的1/8并受共享余量限制;不从未执行的配置上限领取额度,不增加专用预留。节点额度不能当作转移/时间/内存上限。原成员保留仍不证明后续能力前缀和药水审计不受影响,完整请求须核对原成员、最终政策与实际总成本。 - `AdaptiveNoveltyRefinement` 为默认关闭的后置结构探索实验。原 Beam 组合保留,补充节点与时间分别从该组合实际消费量领取至多1/8,并扣主搜索既有余量;不能由配置上限或后续审计领取。达标跳过须复用完整目标与治疗保护。新增成本可影响后续审计,因此按完整请求终局验证。节点额度不等于转移/分配/内存上限;新颖性 `time_limit` 独立记账,不与回合层节点/时间计数混淆,也不将受墙钟影响的观察冒充固定工作量证据。 - `ReallocatedRefinementPortfolio` 将普通默认组合的 plain 成员省去,并追加既有有界进攻成员;只对隐式默认布局生效,显式成员/关闭组合/新颖性与其他排序实验保持原语义。额外额度仍至多为此前组合实际展开的1/8并扣共享余量,无新增预留;节点额度不是转移或内存上限。原窄/宽/次段/基础分/能力与后续审计保留,但省去普通成员可能丢失独有好解。不得声称质量不降或学习型可达界;独立test已知Regent首领多损2 HP,托管/RSS尾项需单列。旧学习选择器不得裁决新布局。基线/候选须比较完整请求,单开关接线与冻结组合等价、跨预设、交错成本和原生完整部署分别验收;见组合再分配证据。 - Steam 自动 GC 接入只准备下次启动:`RuntimeGcStartupConfig` 原子更新游戏 runtimeconfig 并记录/恢复原 GC 字段;`RuntimeGcProfile` 只以启动 AppContext 与实际 CLR 状态生效。默认无头测试不改配置,验证必须在自有隔离实例显式启用;不将文件已写入、普通 .NET 子进程或无头验证当作可见 Steam 链路通过。直接退订无法运行恢复逻辑,须明确披露并提供关闭入口。 - 由获得金币等间接命令触发的已持有回复来源必须计入现有界。DragonFruit 未证明合法触发总数时保留无限回复上界;缺席或熔化只排除该机制。不得将模拟支持、原版程序集身份或非 gameplay Ignored 分类当作回复闭包证明;新增回调先验证分支、Fork 与 live 隔离,再测完整请求。