feat: 任务书 11,指标名加候选前缀、消融重做接着改、判重说明补关键设定

- 假设专用指标短名不能含"."(最长 64),冻结时由 materials 的 freezeProtocol 改为全名"候选编号.短名";可引用清单用全名,已占用清单只剩任务指标和两个保留键。
- 消融格核验不通过重做时,工作目录是上一次交的这一格代码的副本,能读的版本加上它,完整代码照旧列出;消融实现提示词同步改。
- jev 判重材料说明补 keySettings 一句。
- 结构.md 第八部分 vocab、materials、jev,WORK_LOG 同步更新。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-03 06:40:40 -04:00
parent f623fb78a8
commit 13a7e60355
20 changed files with 156 additions and 57 deletions
+11 -7
View File
@@ -12,6 +12,7 @@ import {
} from "../src/rules/index.ts";
import {
buildMaterial,
freezeProtocol,
readPrompts,
type CodeChanges,
type FrozenProtocol,
@@ -24,6 +25,7 @@ import { join } from "node:path";
// materials 测试共用:在真实账本(临时文件)里一步步写入一段研究进程。
// 研究者 a1、a2,实验员 x1,核验员 v1。第 1 轮采纳 r1-c1(两个因子),消融测 p1、p2 没测;第 2 轮采纳 r2-c1。
// 第 1 轮两条提案都登记了短名 restart-count,冻结成 r1-c1.restart-count、r1-c2.restart-count;r2-c1 引用前一个。
// 好认的数和字(7.77x 作者自评、5.55x 甲的第一次预测等)用来检查"不该看到的没出现"。
export const study: StudyFacts = {
@@ -62,10 +64,11 @@ const P_A1: Submission<"proposal"> = {
authorEstimate: SEALED_A1,
body: "甲的提案正文",
};
// 乙和甲同一轮互相看不到提案,起了同一个短名 restart-count、定义却不同(参考项目真实账本出过 5 次,任务书 11 第一部分)。
const P_A2: Submission<"proposal"> = {
factors: [factor("收缩半径修复", null)],
safeguards: [],
metrics: { defined: [], reused: [] },
metrics: { defined: [{ id: "restart-count", meaning: "修复阶段重启了几次", unit: "次", direction: "minimize", howMeasured: "修复循环每重启一次加一", missing: "recordMissing" }], reused: [] },
authorEstimate: SEALED_A2,
body: "乙的提案正文",
};
@@ -121,8 +124,9 @@ export class Writer {
}
}
export function protocolOf(p: Submission<"proposal">, round: number, baseline: string, proposals: string[], clauses: string[]): FrozenProtocol {
return { factors: p.factors, safeguards: p.safeguards, metrics: p.metrics, body: p.body, clauses, round, baseline, proposals };
/** 候选 candidate 的冻结协议:照 flow 的做法,用 freezeProtocol 写(新登记的指标改全名)。 */
export function protocolOf(candidate: string, p: Submission<"proposal">, round: number, baseline: string, proposals: string[], clauses: string[]): FrozenProtocol {
return freezeProtocol({ factors: p.factors, safeguards: p.safeguards, metrics: p.metrics, body: p.body, clauses }, candidate, round, baseline, proposals);
}
export function batch(round: number, baseline: number, ranges: Record<string, Record<string, Range>>): { input: BatchInput; output: ReturnType<typeof selectBestExpected> } {
@@ -192,8 +196,8 @@ const STEPS: Array<[string, (w: Writer, s: Record<string, number>) => void]> = [
w.sub("s1-resp", "a1", "response", "r1-c1", null, { replies: [{ critique: CRITIQUE_ID, reply: "甲答复:保留扰动" }], changes: {}, clauses: ["加多起点", "加扰动"], body: "无" });
w.sub("s1-resp", "a2", "response", "r1-c2", null, { replies: [], changes: {}, clauses: ["加修复"], body: "无" });
w.close("s1-resp");
w.protocol("r1-c1", protocolOf(P_A1, 1, "base", ["r1-a1-1"], ["加多起点", "加扰动"]));
w.protocol("r1-c2", protocolOf(P_A2, 1, "base", ["r1-a2-1"], ["加修复"]));
w.protocol("r1-c1", protocolOf("r1-c1", P_A1, 1, "base", ["r1-a1-1"], ["加多起点", "加扰动"]));
w.protocol("r1-c2", protocolOf("r1-c2", P_A2, 1, "base", ["r1-a2-1"], ["加修复"]));
}],
["secondOpen", (w) => w.open("s1-sp", "secondPrediction", 1, ["a1", "a2"])],
["second", (w) => {
@@ -273,8 +277,8 @@ const STEPS: Array<[string, (w: Writer, s: Record<string, number>) => void]> = [
w.sub("s2-resp", "a1", "response", "r2-c1", null, { replies: [], changes: {}, clauses: ["加局部搜索"], body: "无" });
w.sub("s2-resp", "a2", "response", "r2-c2", null, { replies: [], changes: {}, clauses: ["改修复", "加早停"], body: "无" });
w.close("s2-resp");
w.protocol("r2-c1", protocolOf({ ...P_A1, metrics: { defined: [], reused: ["restart-count"] }, factors: [factor("新的局部搜索", "r1-c1-p1"), factor("更多起点", null)], body: "甲的第二轮提案" }, 2, "r1-c1", ["r2-a1-1"], ["加局部搜索"]));
w.protocol("r2-c2", protocolOf({ ...P_A2, factors: [factor("更细的修复", null), factor("早停", null)], body: "乙的第二轮提案" }, 2, "r1-c1", ["r2-a2-1"], ["改修复", "加早停"]));
w.protocol("r2-c1", protocolOf("r2-c1", { ...P_A1, metrics: { defined: [], reused: ["r1-c1.restart-count"] }, factors: [factor("新的局部搜索", "r1-c1-p1"), factor("更多起点", null)], body: "甲的第二轮提案" }, 2, "r1-c1", ["r2-a1-1"], ["加局部搜索"]));
w.protocol("r2-c2", protocolOf("r2-c2", { ...P_A2, factors: [factor("更细的修复", null), factor("早停", null)], body: "乙的第二轮提案" }, 2, "r1-c1", ["r2-a2-1"], ["改修复", "加早停"]));
w.open("s2-sp", "secondPrediction", 2, ["a1", "a2"]);
const ranges = { "r2-c1": { a1: r(1.2, 1.24, 1.3), a2: r(1.19, 1.22, 1.27) }, "r2-c2": { a1: r(1.18, 1.2, 1.22), a2: r(1.17, 1.2, 1.22) } };
for (const [c, rs] of Object.entries(ranges)) for (const [a, range] of Object.entries(rs)) w.sub("s2-sp", a, "secondPrediction", c, null, { range, body: "理由" });