feat: 接通实现核验修复到正向运行采纳
任务书16第二块:角色分派与每调用轻量检查,提交及代码原子记账,按次数核验修复且耗尽不跑,串行正式运行及恢复引用指标,采纳含null统一公开。451项免费测试通过,全新上下文独立审阅未发现问题;真实研究验收仍待进行。
This commit is contained in:
@@ -4,9 +4,12 @@ import { join } from "node:path";
|
||||
import { test } from "node:test";
|
||||
import { stepList, type ResearchConfig } from "../src/config/index.ts";
|
||||
import type { AppendKind, Content, LedgerRecord } from "../src/ledger/index.ts";
|
||||
import type { StudyRecord } from "../src/materials/index.ts";
|
||||
import { Board, forwardNotRunEvent, type StudyRecord } from "../src/materials/index.ts";
|
||||
import { runBalance } from "../src/rules/index.ts";
|
||||
import { definition, exited } from "./ledger-helpers.ts";
|
||||
import { judged } from "./materials-helpers.ts";
|
||||
import { nextStep } from "../src/flow/next-step.ts";
|
||||
import type { Json, SubmissionKind } from "../src/vocab/index.ts";
|
||||
import type { Json, Submission, SubmissionKind } from "../src/vocab/index.ts";
|
||||
import { fullConfig } from "./config-helpers.ts";
|
||||
|
||||
// flow 的"下一步做什么"(任务书 12 第六部分):纯函数,手写账本记录,看它给出的下一步。
|
||||
@@ -337,8 +340,8 @@ test("第二次预测关闭:选批", () => {
|
||||
assert.deepEqual(nextStep(roundOne("secondPrediction").records), { do: "selectBatch", round: 1 });
|
||||
});
|
||||
|
||||
test("选批做完:停下,原因\"实现还没写\"", () => {
|
||||
assert.deepEqual(nextStep(roundOne("selectBatch").records), { do: "halt", reason: "实现还没写(任务书 16)", objects: [] });
|
||||
test("选批做完:开实现阶段,每个入选候选固定一位实验员", () => {
|
||||
assert.deepEqual(nextStep(roundOne("selectBatch").records), { do: "openStage", stageId: "r1-implementation", stage: "implementation", round: 1, roster: ["experimenter-r1-c1"] });
|
||||
});
|
||||
|
||||
test("关掉第一次预测:第 1 轮写一条按配置跳过(对象 r1-firstPrediction),接着开挑刺", () => {
|
||||
@@ -354,3 +357,149 @@ test("关掉第一次预测:第 1 轮写一条按配置跳过(对象 r1-firs
|
||||
book.add("event", { event: "skippedByConfig", reason, objects: ["r1-firstPrediction"] });
|
||||
assert.deepEqual(nextStep(book.records), { do: "openStage", stageId: "r1-critique", stage: "critique", round: 1, roster: R });
|
||||
});
|
||||
|
||||
|
||||
// ⑨–⑫:预期动作手写,不调模型、Jev 或 Docker。
|
||||
const X = ["experimenter-r1-c1", "experimenter-r1-c2"];
|
||||
const V = ["verifier-r1-c1", "verifier-r1-c2"];
|
||||
|
||||
function batchTwo(maxRepairs: number): Book {
|
||||
const book = roundOne("secondPrediction");
|
||||
const record = book.records.find((r) => r.kind === "config")!;
|
||||
(record.content as unknown as StudyRecord).config = { ...fullConfig(), maxRepairs } as unknown as Json;
|
||||
return book.add("decision", { decision: "batch", round: 1, rule: "bestExpected", ruleVersion: 1, params: null, seed: "s", input: null, output: { chosen: C } });
|
||||
}
|
||||
|
||||
function implemented(book: Book): Book {
|
||||
book.open("r1-implementation", "implementation", 1, X);
|
||||
for (const [i, candidate] of C.entries()) book.sub("r1-implementation", X[i]!, "implementation", candidate, null);
|
||||
return book.add("stageClose", { stageId: "r1-implementation" });
|
||||
}
|
||||
|
||||
function verified(book: Book, n: number, candidate: string, passed: boolean): Book {
|
||||
// 对应真实 15-tight-2 的 submissions created_seq=173(墙约束行和右端错位)、194(修复后通过)。
|
||||
// 只转录驱动程序所需的逐项 found,不伪造 Jev 的判断或模型运行。
|
||||
const content: Submission<"verification"> = {
|
||||
clauses: [{ clause: "c1", found: passed, where: passed ? "initial.py 墙约束行和右端已对齐" : "initial.py:225-228 与 243-246:墙约束行和右端错位" }],
|
||||
factors: [{ factor: "p1", found: passed, where: "LP 墙约束" }],
|
||||
safeguards: [], unassigned: [], body: passed ? "通过" : "解的不是协议写的线性规划",
|
||||
};
|
||||
return book.add("submission", { stageId: `r1-verification-${n}`, author: `verifier-${candidate}`, kind: "verification", target: candidate, item: null, version: 1, content, jev: null });
|
||||
}
|
||||
|
||||
function firstVerification(book: Book, a: boolean, b: boolean): Book {
|
||||
implemented(book).open("r1-verification-1", "verification", 1, V);
|
||||
verified(book, 1, C[0]!, a);
|
||||
verified(book, 1, C[1]!, b);
|
||||
return book.add("stageClose", { stageId: "r1-verification-1" });
|
||||
}
|
||||
|
||||
function recordForward(book: Book, candidate: string, n: number, ending: "valid" | "notStarted" | "timeout"): Book {
|
||||
const run = `r1-forward-${candidate}-${n}`;
|
||||
book.add("runPlanned", { run, purpose: "forward", round: 1, object: candidate, definition });
|
||||
if (ending === "notStarted") return book.add("runResult", { run, process: { ending, reason: "Docker 未启动" }, judged: null });
|
||||
book.add("runStarted", { run });
|
||||
const process = ending === "timeout" ? { ending: "timeout" as const, wallSeconds: measured(120), cpuSeconds: measured(100), peakMemoryBytes: measured(1024) } : exited;
|
||||
return book.add("runResult", { run, process, judged: ending === "valid" ? judged(1.25, "main") : null });
|
||||
}
|
||||
|
||||
const forward = (candidate: string, n: number) => ({ do: "forwardRun", round: 1, candidate, run: `r1-forward-${candidate}-${n}` });
|
||||
|
||||
test("实现的任务同时可派;已提交后中断不重派,等全体交齐关阶段后才核验", () => {
|
||||
const book = batchTwo(1).open("r1-implementation", "implementation", 1, X);
|
||||
assert.deepEqual(nextStep(book.records), { do: "dispatch", stageId: "r1-implementation", tasks: C.map((object, i) => ({ actor: X[i], kind: "implementation", object })) });
|
||||
book.sub("r1-implementation", X[0]!, "implementation", C[0]!, null);
|
||||
book.call("r1-implementation", X[0]!, "implementation", C[0]!, 1, { wallSeconds: { status: "unmeasured", reason: "进程中断" }, status: "failed", reason: "进程中断" });
|
||||
assert.deepEqual(nextStep(book.records), { do: "dispatch", stageId: "r1-implementation", tasks: [{ actor: X[1], kind: "implementation", object: C[1] }] });
|
||||
book.sub("r1-implementation", X[1]!, "implementation", C[1]!, null);
|
||||
assert.deepEqual(nextStep(book.records), { do: "closeStage", stageId: "r1-implementation" });
|
||||
book.add("stageClose", { stageId: "r1-implementation" });
|
||||
assert.deepEqual(nextStep(book.records), { do: "openStage", stageId: "r1-verification-1", stage: "verification", round: 1, roster: V });
|
||||
});
|
||||
|
||||
test("15-tight-2 的一次修复路径:核验关后才派原实验员,修复关后只重验修过的候选", () => {
|
||||
const book = implemented(batchTwo(1)).open("r1-verification-1", "verification", 1, V);
|
||||
verified(book, 1, C[0]!, false);
|
||||
verified(book, 1, C[1]!, true);
|
||||
assert.deepEqual(nextStep(book.records), { do: "closeStage", stageId: "r1-verification-1" });
|
||||
book.add("stageClose", { stageId: "r1-verification-1" });
|
||||
assert.deepEqual(nextStep(book.records), { do: "openStage", stageId: "r1-repair-1", stage: "implementation", round: 1, roster: [X[0]] });
|
||||
book.open("r1-repair-1", "implementation", 1, [X[0]!]);
|
||||
assert.deepEqual(nextStep(book.records), { do: "dispatch", stageId: "r1-repair-1", tasks: [{ actor: X[0], kind: "repair", object: C[0] }] });
|
||||
book.sub("r1-repair-1", X[0]!, "repair", C[0]!, null);
|
||||
assert.deepEqual(nextStep(book.records), { do: "closeStage", stageId: "r1-repair-1" });
|
||||
book.add("stageClose", { stageId: "r1-repair-1" });
|
||||
assert.deepEqual(nextStep(book.records), { do: "openStage", stageId: "r1-verification-2", stage: "verification", round: 1, roster: [V[0]] });
|
||||
book.open("r1-verification-2", "verification", 1, [V[0]!]);
|
||||
assert.deepEqual(nextStep(book.records), { do: "dispatch", stageId: "r1-verification-2", tasks: [{ actor: V[0], kind: "verification", object: C[0] }] });
|
||||
verified(book, 2, C[0]!, true);
|
||||
assert.deepEqual(nextStep(book.records), { do: "closeStage", stageId: "r1-verification-2" });
|
||||
book.add("stageClose", { stageId: "r1-verification-2" });
|
||||
assert.deepEqual(nextStep(book.records), forward(C[0]!, 1));
|
||||
});
|
||||
|
||||
test("修复次数从关闭的阶段数出:两次修复后仍失败,逐候选写不跑事件,不占预算", () => {
|
||||
const book = firstVerification(batchTwo(2), false, false);
|
||||
for (let n = 1; n <= 2; n++) {
|
||||
assert.deepEqual(nextStep(book.records), { do: "openStage", stageId: `r1-repair-${n}`, stage: "implementation", round: 1, roster: X });
|
||||
book.open(`r1-repair-${n}`, "implementation", 1, X);
|
||||
for (const [i, candidate] of C.entries()) book.sub(`r1-repair-${n}`, X[i]!, "repair", candidate, null);
|
||||
book.add("stageClose", { stageId: `r1-repair-${n}` });
|
||||
assert.deepEqual(nextStep(book.records), { do: "openStage", stageId: `r1-verification-${n + 1}`, stage: "verification", round: 1, roster: V });
|
||||
book.open(`r1-verification-${n + 1}`, "verification", 1, V);
|
||||
for (const candidate of C) verified(book, n + 1, candidate, false);
|
||||
book.add("stageClose", { stageId: `r1-verification-${n + 1}` });
|
||||
}
|
||||
for (const candidate of C) {
|
||||
const next = nextStep(book.records);
|
||||
assert.equal(next.do, "forwardNotRun");
|
||||
if (next.do !== "forwardNotRun") throw new Error("应写不跑事件");
|
||||
assert.equal(next.candidate, candidate);
|
||||
assert.match(next.reason, /第 3 次核验仍不通过,修复次数上限 2 已用完/);
|
||||
assert.match(next.reason, /解的不是协议写的线性规划/);
|
||||
book.add("event", forwardNotRunEvent(candidate, next.reason));
|
||||
}
|
||||
assert.deepEqual(runBalance(13, new Board(book.records).runStates()), { charged: 1, reserved: 0, balance: 12 });
|
||||
assert.deepEqual(nextStep(book.records), { do: "adopt", round: 1 });
|
||||
});
|
||||
|
||||
test("maxRepairs=0:第一次核验失败就记不跑,另一候选仍可串行运行", () => {
|
||||
const book = firstVerification(batchTwo(0), false, true);
|
||||
const next = nextStep(book.records);
|
||||
assert.equal(next.do, "forwardNotRun");
|
||||
if (next.do !== "forwardNotRun") throw new Error("应写不跑事件");
|
||||
book.add("event", forwardNotRunEvent(next.candidate, next.reason));
|
||||
assert.deepEqual(nextStep(book.records), forward(C[1]!, 1));
|
||||
});
|
||||
|
||||
test("正向串行:上次未启动起新编号;已登记未结束必须先恢复;超时也扣次且不重跑;采纳前不公开", () => {
|
||||
const book = firstVerification(batchTwo(1), true, true);
|
||||
assert.deepEqual(nextStep(book.records), forward(C[0]!, 1));
|
||||
recordForward(book, C[0]!, 1, "notStarted");
|
||||
assert.deepEqual(nextStep(book.records), forward(C[0]!, 2));
|
||||
assert.deepEqual(runBalance(13, new Board(book.records).runStates()), { charged: 1, reserved: 0, balance: 12 });
|
||||
const run = `r1-forward-${C[0]}-2`;
|
||||
book.add("runPlanned", { run, purpose: "forward", round: 1, object: C[0]!, definition });
|
||||
assert.throws(() => nextStep(book.records), /登记了还没有结果:恢复入口应当已经核对过/);
|
||||
assert.deepEqual(runBalance(13, new Board(book.records).runStates()), { charged: 1, reserved: 1, balance: 11 });
|
||||
book.add("runStarted", { run });
|
||||
assert.throws(() => nextStep(book.records), /登记了还没有结果/);
|
||||
book.add("runResult", { run, process: exited, judged: judged(1.25, "main") });
|
||||
assert.deepEqual(nextStep(book.records), forward(C[1]!, 1));
|
||||
recordForward(book, C[1]!, 1, "timeout");
|
||||
assert.deepEqual(nextStep(book.records), { do: "adopt", round: 1 });
|
||||
assert.deepEqual(runBalance(13, new Board(book.records).runStates()), { charged: 3, reserved: 0, balance: 10 });
|
||||
const before = new Board(book.records);
|
||||
assert.ok(before.runs().filter((r) => r.plan.purpose === "forward").every((r) => !before.runPublic(r)));
|
||||
book.add("decision", { decision: "adopt", round: 1, rule: "adopt", ruleVersion: 1, params: null, seed: null, input: null, output: { adopted: null } });
|
||||
const after = new Board(book.records);
|
||||
assert.ok(after.runs().filter((r) => r.plan.purpose === "forward").every((r) => after.runPublic(r)));
|
||||
assert.deepEqual(nextStep(book.records), { do: "halt", reason: "消融还没写(任务书 17)", objects: [] });
|
||||
});
|
||||
|
||||
test("采纳只有一个因子的候选也统一在 listCells 停下,不擅自开收尾", () => {
|
||||
const book = firstVerification(batchTwo(1), true, true);
|
||||
for (const c of C) recordForward(book, c, 1, "valid");
|
||||
book.add("decision", { decision: "adopt", round: 1, rule: "adopt", ruleVersion: 1, params: null, seed: null, input: null, output: { adopted: C[0]! } });
|
||||
assert.deepEqual(nextStep(book.records), { do: "halt", reason: "消融还没写(任务书 17)", objects: [] });
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user