30e4d98ed2
用户 2026-10-01 同意:提交字段定义放 vocab、submissions 只判收不收;vocab 可放规范序列化与哈希两个函数,上限 600 行。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
167 lines
11 KiB
Markdown
167 lines
11 KiB
Markdown
# 任务书 01:vocab(共用词汇)与工具链
|
||
|
||
这是 InfoRSI 的第一个代码任务。项目里现在只有文档,没有代码。这个任务做两件事:
|
||
|
||
1. 搭好工具链:npm 包、TypeScript、测试、依赖方向检查;
|
||
2. 写 vocab 模块:各模块共用的类型、名单、提交字段定义,以及两个函数。
|
||
|
||
本任务书的内容已由用户和监督者在 2026-10-01 一起确定。下面说的"监督者",是在参考项目目录里和用户讨论设计的另一个会话。
|
||
|
||
## 开工前先读
|
||
|
||
- `CLAUDE.md`:全部。
|
||
- `docs/结构.md`:
|
||
- 第一部分(切分原则);
|
||
- 第二部分(模块表,以及表下面讲 vocab 的那一段);
|
||
- 第六部分(模块化程度与检查);
|
||
- 第七部分(规模)。
|
||
- `docs/方法.md`:
|
||
- 第二部分(核心概念);
|
||
- 第三部分(角色);
|
||
- 4.2、4.3(流程里的各个阶段);
|
||
- 第五部分(每种提交,**这是提交字段的唯一依据**);
|
||
- 第七、八部分(运行要记录什么)。
|
||
- 参考项目(只读,不要改):`/home/iomgaa/Projects/RivalBits`
|
||
- `src/core/types.ts`:旧的共用类型。下面"保留与删除"一节说明哪些要、哪些不要;
|
||
- `src/rounds/submissions.ts`、`src/rounds/task-submissions.ts`:旧的提交字段,里面混着收件检查。只借字段本身,按方法.md 第五部分重写;
|
||
- `package.json`、`tsconfig.json`:版本号可以参考。
|
||
|
||
## 一、工具链
|
||
|
||
- 建一个 npm 包,`"type": "module"`,Node ≥ 22.19(本机是 22.22.2)。
|
||
- 这次只装这次用得到的依赖:`typebox` 1.3.7、`typescript`、`@types/node`、`dependency-cruiser`。
|
||
- Pi 的包等写 agents 模块时再装。
|
||
- Pi 0.85.1 用的也是 `typebox` 1.3.7,这次定的字段定义以后要直接当 Pi 工具的参数用,所以版本必须一致。
|
||
- `npm run check`:TypeScript 类型检查加 dependency-cruiser,两项都要过。
|
||
- `npm test`:用 Node 自带的 `node --test`。
|
||
- dependency-cruiser 把 `docs/结构.md` 第六部分列的规则全部写进去,模块按 `src/<模块名>/` 的目录来认:
|
||
- 依赖方向按第二部分的模块表;
|
||
- 不许循环引用;
|
||
- 不许绕过 `index.ts` 直接引用模块内部的文件;
|
||
- rules 和 vocab 不许引用文件、数据库、网络、子进程和 Pi;
|
||
- 只有 ledger 能用 SQLite,只有 agents 和 plugin 能用 Pi,只有 runner 和 workspace 能起子进程;
|
||
- tasks 不许引用 runner。
|
||
|
||
现在只有 vocab 一个目录,但规则要一次写全,后面的模块建目录就自动受检查。
|
||
- 要证明这些规则真的会报错,不能只是写了配置:临时写几处违规的引用(比如 vocab 引用 `node:fs`、一个模块绕过 `index.ts`),把 `npm run check` 的报错输出记下来,然后删掉这些违规引用。
|
||
|
||
## 二、vocab 放什么
|
||
|
||
判断标准(来自结构.md):一样东西要有两个互相不能引用的模块都用到,才放进 vocab;只有一个模块用的,放在那个模块里。上限 600 行,预期 450–600 行。
|
||
|
||
建议分四个文件,由 `src/vocab/index.ts` 统一对外。文件名和英文标识符你来定,以读得懂为准。
|
||
|
||
### 1. 基础
|
||
|
||
- `Json` 类型。
|
||
- "测到 / 测不到"的取值:测到就带值,测不到就带原因。全项目凡是可能测不到的量(资源用量、分数、指标、价格)都用它,不用 0 或 null 冒充测不到。
|
||
- 指标方向:越大越好、越小越好,只有这两种。
|
||
- 编号的格式:只允许字母、数字和 `._-`,长度有限。编号会被拼进文件路径和命令行,所以要限制。写成一条 TypeBox 的字段规则,各字段定义里复用,不写成函数。
|
||
- 两个函数:
|
||
- **规范序列化**:对象的键排序后再拼;数字必须是有限数;只接受纯 JSON 对象。这样内容相同就一定得到同一个字符串;
|
||
- **哈希**:对规范序列化的结果算 sha256。
|
||
|
||
这是 vocab 里仅有的两个函数。
|
||
|
||
### 2. 名单
|
||
|
||
- **三个角色**:研究者、实验员、核验员。
|
||
- **研究者阶段和提交种类**:按方法.md 4.2、4.3 和第五部分列出。每种提交写清两件事:属于哪个阶段、由哪个角色交。这份对应关系写成一张常量表,以后 ledger、materials、submissions、flow、agents 都从这里取,不在别处另写。
|
||
- 监督者整理的对应关系如下,作参考。以方法.md 为准,对不上时按方法.md 来,并在最后的报告里写出差别:
|
||
|
||
| 提交 | 阶段 | 角色 |
|
||
|---|---|---|
|
||
| 入口 | 写入口 | 研究者 |
|
||
| 讨论 | 讨论 | 研究者 |
|
||
| 志愿 | 认领 | 研究者 |
|
||
| 提案 | 提案 | 研究者 |
|
||
| 第一次预测 | 第一次预测 | 研究者 |
|
||
| 挑刺 | 挑刺 | 研究者 |
|
||
| 回应 | 回应 | 研究者 |
|
||
| 统一 | 回应 | 研究者 |
|
||
| 第二次预测 | 第二次预测 | 研究者 |
|
||
| 实现 | 实现 | 实验员 |
|
||
| 修复 | 实现 | 实验员 |
|
||
| 核验 | 核验 | 核验员 |
|
||
| 消融实现 | 消融实现 | 实验员 |
|
||
| 消融核验 | 消融核验 | 核验员 |
|
||
| 解释 | 解释 | 研究者 |
|
||
| 收尾 | 收尾 | 研究者 |
|
||
|
||
- 程序自己做的步骤,比如判重、选批、采纳、选格,不是提交阶段,不放这里。步骤清单归 config。
|
||
- 私人笔记不在这次范围内。
|
||
|
||
### 3. 运行与指标
|
||
|
||
- **指标定义**,包括:编号、层次(最终 / 常规辅助 / 假设专用)、含义、单位、方向、怎么采样和汇总、"测不到时怎么办"。
|
||
- "测不到时怎么办"只有两档:缺了只记缺失;缺了整次作废。
|
||
- 每一档的后果用一句白话写在常量里,字段说明和给模型看的材料都用这一份。白话的内容见方法.md 第五部分"指标"。
|
||
- **运行定义**:tasks 交给 runner,告诉它怎么起这个进程。要能回答这几件事:
|
||
- 命令和工作目录;
|
||
- 镜像:按 sha256 钉死,不接受 tag;运行时必须写明;
|
||
- 限时、核数;
|
||
- 环境变量:候选进程**不继承**宿主的环境变量。类型上只允许写 false。
|
||
- 原因:参考项目实测过,宿主环境被污染时,同一份代码的分数会从 0.9598 悄悄变成 0.8849,退出码是 0,没有任何报错。这属于"出错后无法察觉"的那一类。
|
||
- 参考项目里环境变量分成两块("协议那块"和"逐候选那块"),是为了算两个"可比条件哈希"。那两个哈希这次删掉了,所以这里只要一块。
|
||
- **运行结果**,分两层:
|
||
- runner 交出的进程层面结果:有没有启动;以什么方式结束(正常退出、超时、被取消、没启动);退出码;CPU 秒、墙钟时间、峰值内存。资源用量都可能测不到,用"测到 / 测不到"表示。
|
||
- tasks 交出的判分结果:
|
||
- 判定:三选一,算数 / 不算数 / 判不了,附理由;
|
||
- 分数;
|
||
- 各指标的取值;
|
||
- 答案路径和各条保障动手的次数(方法.md 第五部分"答案路径")。读不到,或者读到的取值不在位置表里,都要有明确状态;
|
||
- 一份任务自己的附加记录,任务想记什么就记什么,比如填圆的合法化。
|
||
- **模型用量**:普通输入、缓存命中、缓存写入、输出四种 token 数,加上价格。价格可能测不到。
|
||
|
||
### 4. 提交字段
|
||
|
||
- 按方法.md 第五部分,每种提交写一个 TypeBox 字段定义。同一份定义要同时当三样东西用:类型、收件时的格式检查、发给模型的提交工具参数。
|
||
- 字段说明也写在定义里,它会原样发给模型。
|
||
- 方法.md 要求每个字段都写明出口,比如"只有一个因子就写一个"、"不适用:原因"、"没有:为什么";
|
||
- 说明用中文。
|
||
- **三个数**是一个共用的定义:q₁、q₅、q₉ 三个有限数。
|
||
- 正文统一是一个 markdown 字符串字段,程序不拆它。
|
||
- 不需要写的字段:
|
||
- 只存不读的栏目、程序自己推得出的栏目,不设(方法.md 第五部分总原则);
|
||
- 编号由程序分配的(候选编号、挑刺编号),不放进模型要填的字段。
|
||
- 跨字段的规则**不在这里写**,留给以后的 submissions 模块。比如:q₁ ≤ q₅ ≤ q₉;因子数不超过上限;同一份提案里两个因子不能延续同一个因子;解释最多 M 条。字段定义只管单个字段长什么样。
|
||
|
||
## 三、参考项目 `src/core/types.ts` 的保留与删除
|
||
|
||
| 处理 | 内容 |
|
||
|---|---|
|
||
| 改写后保留 | `Json`、`Measurement`、`Direction`、`MetricDefinition` 与两档"测不到时怎么办"、`ModelUsage`、`RunResult` 里的启动状态和资源用量、`canonical`、`hash`、运行定义里"镜像按 sha256 钉死、运行时写明、不继承宿主环境变量"这几条 |
|
||
| 删除 | `Lease`、`StudyStatus`(改用文件锁;进度从账本现算) |
|
||
| 删除 | 观测量表、观测量四组、`HardRule`、`validateObservable*`、`validateObservationSet`、`hardRuleVerdict`(不再用模型审查观测量;硬规则校验以后放进 tasks 内部) |
|
||
| 删除 | `comparisonConditionsHash`、`scoreConditionsHash`,以及为它们分出的两块环境变量 |
|
||
| 删除 | `assert`、`finite`、`positiveInteger`、`nonempty`、`identifier`、`validateManifest`、`validateMetric`、`validateRound`、`validateLimits`、`thresholds`(改用 TypeBox 字段定义检查) |
|
||
| 删除 | `Thresholds`、`StudyLimits`、`ComputeLimits`、`processEnvironment`、`collectedMetrics`、`worstCaseCost`、`RoundDefinition`、`SYNERGY_LABELS`(都只有一个模块用,等写那个模块时放进去) |
|
||
| 不搬 | 注释里的修改历史和"参考项目以前怎样"的说明。注释只写现在 |
|
||
|
||
`assertNever` 这类只有一两行的类型辅助,如果几个模块确实都要用,可以放进来,但要先说清楚哪几个模块会用它。
|
||
|
||
## 四、测试
|
||
|
||
- vocab 基本没有逻辑,字段定义不写逐字段的测试。
|
||
- 规范序列化和哈希各写测试。预期值要独立得到,不能拿实现算出来的结果当预期值:
|
||
- 规范序列化的预期字符串,自己手写;
|
||
- 哈希的预期值,用命令行的 `sha256sum` 算。
|
||
- 至少覆盖这几种情况:键的顺序不同,结果相同;嵌套数组;遇到 NaN 或 Infinity 报错;遇到带自定义原型的对象报错。
|
||
- 每种提交挑一份合法的样例,确认能通过字段定义的检查。这一步也是在检查字段写得是不是方法.md 第五部分的意思。
|
||
|
||
## 五、完成后要更新的文档
|
||
|
||
- `docs/结构.md` 第八部分:补上 vocab 对外的类型、名单和两个函数,每项一句话。
|
||
- `WORK_LOG.md`:按它的格式更新当前状态。
|
||
- 不新建其他 md 文件。
|
||
|
||
## 六、验收与报告
|
||
|
||
做完后本地提交,然后在回复里交一份报告,监督者会对着实际文件逐项核对:
|
||
|
||
1. 提交号,新增文件列表,每个文件的行数,vocab 的总行数。
|
||
2. `npm run check` 和 `npm test` 的完整输出。
|
||
3. 临时违规引用时 `npm run check` 的报错输出(见第一部分最后一条)。
|
||
4. 你和这份任务书或方法.md 不一致的地方,以及为什么。
|
||
5. **规则不清楚的地方**:读 CLAUDE.md、结构.md、方法.md 时,哪里让你犹豫、哪里两份文件说法不一致、哪里你是靠猜的。这一条对这次任务特别重要,没有就写"没有"。
|