# 任务书 02:rules(研究规则) 写 rules 模块:方法.md 第六部分的全部公式和常数,以及第七部分的余额计算、4.2 的入口分配。它是纯计算:输入数字,输出数字,不碰文件、数据库、模型,也不用全局随机数。 本任务书的内容已由用户和监督者在 2026-10-02 一起确定。下面说的"监督者",是在参考项目目录里和用户讨论设计的另一个会话。 按 CLAUDE.md,这一块是"账本"标准:每条规则都要有独立来源的预期值,而且要另派一个全新上下文的子 Agent 审阅。 ## 开工前先读 - `CLAUDE.md`:全部。 - `docs/结构.md`: - 第二部分(rules 在模块表里的位置和"几条边界"); - 第五部分(可替换点,尤其是"为了让换规则的实验做得对"那五条); - 第八部分(vocab 已经导出的类型)。 - `docs/方法.md`: - 第二部分(核心概念); - 4.2(入口分配)、4.3 ⑧ ⑫ ⑬ ⑮ ⑰(程序做的决定); - **第六部分全文,这是公式的唯一依据**; - 第七部分(预算与扣次,2026-10-02 刚改过:计算时间不再是预算,只记录); - 第九部分(决定的重算、种子、同一格只结算一次); - 第十一部分(可以换的规则); - 第十二部分(已知局限)。 - `WORK_LOG.md`、`src/vocab/`:已经有的东西。 - 参考项目(只读,不要改):`/home/iomgaa/Projects/RivalBits` - `src/decision/info.ts`、`src/decision/ablation.ts`、`src/decision/rules.ts`:旧的数学规则; - `src/budget/rules.ts`:旧的扣次规则; - `src/controller/steps/ablation.ts` 的结算部分(确认与否定、分不开、结算内容),这部分和写数据库的代码混在一起,只取数学; - `src/rounds/belief-book.ts` 里算战绩和合并范围的部分; - `tests/info.test.ts`、`tests/ablation.test.ts`、`tests/rules.test.ts`:旧测试,看它测了哪些情况; - `tests/fixtures/calc15/` 和 `research-wiki/设计-15-计算/calc15.py`:独立的 Python 计算,见第四部分。 ## 一、范围 对外提供七组函数,都经 `src/rules/index.ts` 导出。下面写的是"要算什么",函数名、文件怎么分由你来定。分文件时按组分,一组一个或两个文件。 ### 1. 范围与合并分布(方法.md 6.1–6.3) - 一个人的三个数 → "低于 x 的把握"折线:五个点,两端补尾巴。三个数严格递增(方法.md 第五部分),每一段宽度都大于 0,没有尖峰。 - 越小越好的任务:合并之后、计算之前换算成改进量,一成和九成对调。 - 开放预留:正向时一次选批里所有人、所有候选共用一个范围;消融时每格各定一个范围。 - 合并:(1 − λ) × 各人平均 + λ × 开放预留。同一人交了几条解释时,他那一份在几条之间平分。 - 从合并分布读出一成、一半、九成,给信念本显示"大家合起来的范围"。 ### 2. 正向:入池、选批、采纳(6.4、6.5) - 入池判断。 - 批内最好期望 V(S),以及选批。选批有两条规则: - 批内最好期望:列出全部组合,V 完全相等时按候选编号定; - 均匀随机:从候选池的全部候选里随机抽,不看入池门槛。 - 分数尺读数,只记录。 - 选批的输出要包含方法.md 6.4"选批记录写入"列的全部内容。 - 采纳线:有已知最好、没有已知最好两种情况,下限 ε/100,B 超过 K\* 时也取 ε/100。 - 采纳判断:只看实测分数,最好的有效候选高出采纳线以上才采纳。 ### 3. 消融结算(6.6,4.3 ⑬ ⑰) - 列格:被采纳改法的每个因子一格。 - 撑几成;G ≤ 0 时报错。 - 相对交互量和配合关系标签,按方法.md 那张表从上往下判。rules 只返回标签代号,"给下一轮的话"这类中文由以后的 materials 写。 - 每格的五种结局:有效分数、证据不足、没测、跑不起来、一起关。只有"有效分数"进入标签的求和。 - "一起关"是对称的:关 p 连带关 q,和关 q 连带关 p,是同一种设置,已有结果就沿用。 - 每条解释在每个有效格上判确认或否定:落在 [q₁, q₉] 内(含两端)记确认,落在外面记否定。 - "现有测法分不开":两条解释在所有有效格上,确认与否定的序列完全相同。 - 消融中发现:某一格的有效分数比当前基线高出采纳线以上,它就成为新基线。几格都过线时取分数最高的;分数相同时取因子编号小的;"一起关"的格也算。 ### 4. 信息价值与选格(6.7、6.8) - 成分与起始权重:解释合起来占 0.9,研究者之间等权,同一人的几条平分;开放预留占 0.1。 - 方向收益,以及剩余空间 h:有已知最好时 h = max(K\* − f(完整), ε/100);没有时 h = 1。 - 信息价值 VOI(S),两种积分: - 全部格都测:一维积分,逐段多项式精确积分; - 只测一部分格:网格。小段数的规则按 6.7 原文,m^k ≤ 4,000,000,s = min(20, ⌊m ÷ 段数⌋),段数超过 m 时改为等宽切 m 份。 都是确定的算法,同样的输入算两次,结果逐位相同。 - 价值、成本、净值:u、m′、R̂、ĝ₀,按 6.7 原文。 - 选格有四条规则: - 信息价值减成本:只考虑格数不超过"余额 − 1"的非空组合,余额为 0 或 1 时不做消融;净值容差 1e-12;平局先取格数少的,再按因子编号比; - 全测; - 随机抽同样多的格; - 都不测。 没选中的格附上原因("剩余次数不够"或"信息价值不足以抵过成本")和它所在组合的净值。 - 押的因子,以及不押的两种情况(6.8)。权重无从更新时保持起始权重。 ### 5. 信息账(6.9) 这一组就是方法里"唯一的尺子",不随选批、选格规则变。 - 格宽 Δ = ε/100,从本批基线 b 起切。 - 世界比特、惊讶、分歧量。 - 事前把握为 0 时,惊讶返回一个明确的状态,比如"事前把握为 0,惊讶算不出",不拿 0 或无穷大顶替。 - 落点四段、覆盖率。 ### 6. 余额与战绩(第七部分、6.10 第 4 条) - **余额**:从运行记录数出已经扣了几次。 - 确认启动的扣一次(启动后失败、超时、取消都算); - 确认没启动的不扣; - 已经预留、还没有结果的,也先占着名额。 计算时间不是预算,这里不算 CPU 秒。 - 本轮正向批量 k = min(每批上限, 余额);消融最多测"余额 − 1"格。 - **战绩**:中位数偏高几次、偏低几次;被穿过上沿几次、下沿几次;包住几次。另有"作者自评 vs 大家合并"一栏,只收已经跑过、有有效成绩的候选。 - 方法.md 6.10 写的是"分方向写",6.9 写的是"按正向与消融分开"。先按"正向与消融分开"理解,在报告里说明。 信念本里其余的数字,比如每格的撑几成、确认与否定、世界比特、惊讶,结算时已经算好、记在结算记录里,以后由 materials 从记录里取出来写成文字。rules 不另做一份"信念本"函数。 ### 7. 入口分配、种子与规则登记表 - **入口分配**:按方法.md 4.2 的四条规则。N = 1 时直接分第一志愿。 - **种子**:由研究编号、轮次、版本算出,用 vocab 的 `hash`。需要随机数时,从种子确定地展开,同一个种子永远得到同一串数。不用 `Math.random`。 - **规则登记表**:一张"名字 → 函数"的表,每条规则带名字和版本号(从 1 开始)。 - 选批两条:批内最好期望、均匀随机。 - 选格四条:信息价值减成本、全测、随机同格数、都不测。 - 以后的配置写规则名,flow 写决定记录时,规则名、版本、参数、种子都从这里取。 ## 二、写法要求 - **参数从外面传进来。** - λ、u、衰减 r、ε、已知最好、每批上限、N、M 这些,都作为函数参数传入,来自以后冻结的配置。rules 里不写死,也不读环境变量。 - 方法.md 6.11 标"固定"的常数写成 rules 里的常量:±0.2、0.9、1e-12、4,000,000、20。 - 标"跟随 ε"的量(采纳线上下限、剩余空间下限、格宽 Δ),从传进来的 ε 算,不写成 0.01、0.0001。 - **输入是普通的数字和数组,不是账本记录。** 账本还没写,rules 也不应该知道账本长什么样。需要的输入类型 vocab 里有的(比如 `Range`),用 vocab 的;只有 rules 用的,定义在 rules 里。 - **每个决定的输出要足够写成一条决定记录。** 结构.md 第五部分要求决定记录存全部输入和输出,方法.md 6.4、6.7 列了要记哪些数。函数返回值里要有这些中间数,不要只返回"选了谁"。 - **错误**:方法.md 写明要报错的(比如 G ≤ 0),直接抛错,写清是哪条规则、什么输入。其余不加防御性检查,输入的格式由上游的字段定义保证。 - **注释**:写这段在算方法.md 哪一节的哪个量,用小节名引用。不写修改历史。 ## 三、参考项目的保留与删除 | 处理 | 内容 | |---|---| | 改写后保留 | `decision/info.ts`:折线、开放预留、合并、V(S)、选批、比特、惊讶、落点、覆盖、分歧量 | | 改写后保留 | `decision/ablation.ts`:成分模型、信息价值(精确和网格两种)、机会成本、选格、押的因子 | | 改写后保留 | `decision/rules.ts`:撑几成、标签、剩余空间、采纳线、消融中发现 | | 改写后保留 | `budget/rules.ts` 里"一次运行扣不扣"的规则,只留次数,去掉 CPU 秒和墙钟两道闸门 | | 从别处抽出 | `controller/steps/ablation.ts` 里的确认与否定、分不开、结算内容;`rounds/belief-book.ts` 里的战绩和合并范围 | | 删除 | `budget/ablation.ts` 整个文件:份额、照测、欠测、收尾补测、最后一轮预留,以及 `RB_TEST_ABLATION_QUOTA_ZERO` 测试开关。方法里都已删除 | | 删除 | `ABLATION_QUOTA_SHARE`;写死的 0.01、0.0001(改从 ε 推出) | | 删除 | `worldBits` 与 `worldBitsFrom`、`surpriseBits` 与 `surpriseBitsFrom` 的重复,各留一个,都从 b 起切 | | 删除 | `rangeRevision`:方法里没有这个量 | | 删除 | `budget/compute.ts`(`ComputeBudget`、`BudgetExhaustedError`):带状态的闸门不属于纯计算,计算时间也不再是预算 | | 不搬 | `proposalCompleteness`(归 submissions);`changeText`("变好 / 基本不变 / 变差",归 export);`SYNERGY_TEXT` 等标签中文(归 materials);`src/replay/` | 参考项目的公式如果和方法.md 不一致,以方法.md 为准,并在报告里写出差别。 ## 四、测试 预期值必须有独立来源,不能从实现里抄公式算预期值。来源有三种,按可信程度排: 1. **方法.md 里的手算例子**,每个都要变成测试: - 2.44 / 2.52 / 2.62 时,"低于 2.57"的把握是 0.70; - X、Y 单独跑都是 0.010,一起跑是 0.015; - 基线 1.00、完整 1.50,关 p1 得 1.45,关 p2 得 1.10:撑 0.10 和 0.80,i = −0.10,标签"各管各"; - 第七部分的扣次示例表。 2. **你自己写的独立 Python 脚本**,放在 `tests/fixtures/` 下: - 不 import 本项目代码,直接照方法.md 的文字实现; - 把算出的预期值写成 JSON,测试读这份 JSON; - 脚本开头写明用法、对应方法.md 哪一节。 信息价值、选格、押的因子、世界比特这几块必须走这一条。网格和一维精确积分要互相对照:同一组输入在全部格都测时,两种算法的结果应当接近,并写明允许的误差和理由。 3. **参考项目的独立计算**:`research-wiki/设计-15-计算/calc15.py`、`tests/fixtures/calc15/`。 - 它们按旧版方法写,带份额等已经删除的规则。 - 只用和现行方法.md 一致的部分。用之前逐条对照,在报告里写明用了哪些、哪些因为方法变了没用。 - 真实运行数据在 `/home/iomgaa/rb-acceptance/`,只能复制出来读。 还要覆盖这些情况: - 每条规则在边界上的行为:入池正好在一半;采纳线的下限和 B 超过 K\*;净值在 1e-12 附近;余额为 0、1、2;惊讶的事前把握为 0;G ≤ 0 报错。 - 五种结局里只有有效分数进入标签。 - "一起关"对称沿用。 - 分不开的判定。 - 同样的输入算两次结果逐位相同;同一个种子得到同一个随机结果。 - 规则登记表里的每条规则都至少有一条测试。 不靠删断言、改预期值让测试通过。实现和独立脚本对不上时,先查清是谁错了,查的过程写进报告。 ## 五、独立审阅 全部写完、测试通过后,另派一个全新上下文的子 Agent 审阅。它只拿到方法.md 第六、七部分和 `src/rules/`、`tests/` 的代码,不给它看你的思路。 - 让它逐条对照方法.md 找不一致,找出错后不会被发现的地方(比如格宽、种子、平局规则),交回具体的失败场景。 - 它不写 md 文件,结论直接回复给你。 - 它提出的问题,修了的要附测试,没修的写明理由。 ## 六、规模与文档 - 预期 1700–2200 行(不含测试),在结构.md 第七部分粗估的 1500–2500 之内。超过 2500 行就停下来检查:是需求本身复杂,还是专门处理罕见情况的分支在变多。 - 完成后更新: - `docs/结构.md` 第八部分:补 rules 对外的函数和类型,每项一句话; - `WORK_LOG.md`。 - 不新建其他 md 文件。 ## 七、验收与报告 做完后本地提交,然后在回复里交一份报告,监督者会对着实际文件逐项核对: 1. 提交号,新增文件列表,每个文件的行数,rules 的总行数。 2. `npm run check` 和 `npm test` 的完整输出。 3. 每组规则的预期值来自哪里:手算例子、你的 Python 脚本,还是参考项目的计算。参考项目的计算用了哪些、没用哪些、为什么。 4. 独立审阅提出的问题,以及每条怎么处理的。 5. 你和这份任务书、方法.md 或参考项目不一致的地方,以及为什么。 6. **规则不清楚的地方**:读 CLAUDE.md、结构.md、方法.md 时,哪里让你犹豫、哪里两份文件说法不一致、哪里你是靠猜的。方法.md 第六部分写得不够让你直接写成代码的地方,要逐条列出来。没有就写"没有"。