feat: 诊断(任务书 18 第一块):诊断数学、四种提交、一次运行跑多个实验、账本与材料、flow 诊断各步
消融默认关,关掉时解释阶段一并跳过;选诊断实验用信息价值减成本。 eval/diagnosis/research.json 为第三块配置。vocab 字段说明的出口文字随提示词一起改,见下一次提交的 prompts/ 与同文件改动(本次含在内)。 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
+7
-5
@@ -17,7 +17,7 @@ import {
|
||||
type SubmissionKind,
|
||||
} from "../vocab/index.ts";
|
||||
|
||||
// 账本记录的种类(docs/结构.md 第四部分的 11 种记录,细分成下面 19 种),每种一份内容定义(TypeBox)。
|
||||
// 账本记录的种类(docs/结构.md 第四部分的 11 种记录,细分成下面 20 种),每种一份内容定义(TypeBox)。
|
||||
// 下面写"只有一条""只一次"的,由 schema.ts 的唯一约束保证。
|
||||
// 配置、冻结协议、决定、结算的内容由别的模块产生,这里只检查最少的标识字段,其余只检查是 Json。
|
||||
|
||||
@@ -131,7 +131,7 @@ export const KINDS = {
|
||||
submission: Type.Unsafe<StoredSubmission>({}),
|
||||
/**
|
||||
* 3 退回:被退回的那份内容原样存(它可能正是因为不合格式才被退回),连同退回理由。
|
||||
* target 是这次任务的对象,与提交的 target 同义(候选、原提案、消融格,没有对象的写 null):
|
||||
* target 是这次任务的对象,与提交的 target 同义(候选、原提案、消融格、本轮诊断,没有对象的写 null):
|
||||
* 同一人在同一阶段可能对几个对象各做一次同种任务,重新发起时按它找本人这个对象的上一次退回。
|
||||
* jev 是这次退回用到的 Jev 判断(见 JevUsed),判"否"的几问也一起存;没用到 Jev 的写 null。
|
||||
*/
|
||||
@@ -161,11 +161,11 @@ export const KINDS = {
|
||||
/** 6 冻结代码:候选或消融格的代码版本号(由 workspace 给出)和因子位置表。位置表先存 Json。 */
|
||||
code: Type.Object({ object: Id, version: Text, locations: AnyJson }, CLOSED),
|
||||
|
||||
/** 7 运行·登记要跑(占名额):运行编号由 flow 起,一个编号只登记一次;用途、轮次、对象(候选或格;基线没有)、运行定义。 */
|
||||
/** 7 运行·登记要跑(占名额):运行编号由 flow 起,一个编号只登记一次;用途、轮次、对象(候选、格或本轮诊断;基线没有)、运行定义。 */
|
||||
runPlanned: Type.Object(
|
||||
{
|
||||
run: Id,
|
||||
purpose: Type.Enum(["baseline", "forward", "ablation"], { type: "string" }),
|
||||
purpose: Type.Enum(["baseline", "forward", "ablation", "diagnosis"], { type: "string" }),
|
||||
round: Round,
|
||||
object: OptionalId,
|
||||
definition: RunDefinition,
|
||||
@@ -178,7 +178,7 @@ export const KINDS = {
|
||||
runResult: Type.Object({ run: Id, process: ProcessResult, judged: Type.Union([JudgedResult, Type.Null()]) }, CLOSED),
|
||||
|
||||
/**
|
||||
* 8 决定:选批、采纳、选格、押的因子、入口分配、判重合并。decision 是决定种类。
|
||||
* 8 决定:选诊断实验、选批、采纳、选格、押的因子、入口分配、判重合并(提案和诊断实验)。decision 是决定种类。
|
||||
* 输入输出存 Json:ledger 不认识 rules。判重合并的输入里带 Jev 的原始概率。
|
||||
*/
|
||||
decision: Type.Object(
|
||||
@@ -197,6 +197,8 @@ export const KINDS = {
|
||||
|
||||
/** 9 结算:每轮最多采纳一个改法,所以最多一次消融,结算按轮次一轮一条。各格结局、配合关系、解释的确认或否定等先存 Json。 */
|
||||
settlement: Type.Object({ round: Round, result: AnyJson }, CLOSED),
|
||||
/** 9 诊断结算:每轮最多一次诊断,结算也按轮次一轮一条(方法.md 6.12)。每个实验的结局与实测、解释的确认或否定等先存 Json。 */
|
||||
diagnosisSettlement: Type.Object({ round: Round, result: AnyJson }, CLOSED),
|
||||
|
||||
/** 10 模型调用开始:先登记再调用(方法.md 第九部分)。附这次任务的全部材料,用来重现模型当时看到了什么。一次调用只有一条。 */
|
||||
callStarted: Type.Object({ call: Id, actor: Id, stageId: OptionalId, model: Text, materials: AnyJson }, CLOSED),
|
||||
|
||||
+13
-5
@@ -83,7 +83,7 @@ export class Ledger {
|
||||
}
|
||||
|
||||
/**
|
||||
* 追加一条记录,返回存下的那一条。先按种类检查内容,再做写入时的四种拒收检查(rejections.ts)。
|
||||
* 追加一条记录,返回存下的那一条。先按种类检查内容,再做写入时的五种拒收检查(rejections.ts)。
|
||||
* 写提案时,作者自评从提案里拆出来,在同一个事务里另存成一条封存,返回的是提案那一条。
|
||||
*/
|
||||
append<K extends AppendKind>(kind: K, content: Input<K>): LedgerRecord<K> {
|
||||
@@ -117,16 +117,24 @@ export class Ledger {
|
||||
this.#first("stageOpen", "json_extract(content, '$.stageId') = ?", stageId) as LedgerRecord<"stageOpen"> | undefined,
|
||||
latest: (slot) => this.latestSubmission(slot),
|
||||
runStarted: (run) => this.#first("runStarted", "json_extract(content, '$.run') = ?", run) !== undefined,
|
||||
ablationStarted: (round) =>
|
||||
ablationStarted: (round) => this.#purposeStarted("ablation", round),
|
||||
diagnosisStarted: (round) => this.#purposeStarted("diagnosis", round),
|
||||
};
|
||||
|
||||
/** 这一轮有没有某种用途的运行已经确认启动。 */
|
||||
#purposeStarted(purpose: "ablation" | "diagnosis", round: number): boolean {
|
||||
return (
|
||||
this.#one(
|
||||
`SELECT s.seq FROM records s JOIN records p
|
||||
ON p.kind = 'runPlanned' AND json_extract(p.content, '$.run') = json_extract(s.content, '$.run')
|
||||
WHERE s.kind = 'runStarted'
|
||||
AND json_extract(p.content, '$.purpose') = 'ablation'
|
||||
AND json_extract(p.content, '$.purpose') = ?
|
||||
AND json_extract(p.content, '$.round') = ?`,
|
||||
purpose,
|
||||
round,
|
||||
) !== undefined,
|
||||
};
|
||||
) !== undefined
|
||||
);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// 读取
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { SUBMISSION_KINDS, type Stage } from "../vocab/index.ts";
|
||||
import type { Content, Kind, LedgerRecord, SubmissionSlot } from "./kinds.ts";
|
||||
|
||||
// 写入时由 ledger 拒绝的四种情况(docs/结构.md 第四部分"写入时由 ledger 拒绝的几种情况"),在写入的同一个事务里查。
|
||||
// 只有这四种。记录之间别的先后(例如运行结果前要先有登记)和提交种类与阶段对不对得上都不查:
|
||||
// 写入时由 ledger 拒绝的五种情况(docs/结构.md 第四部分"写入时由 ledger 拒绝的几种情况"),在写入的同一个事务里查。
|
||||
// 只有这五种。记录之间别的先后(例如运行结果前要先有登记)和提交种类与阶段对不对得上都不查:
|
||||
// flow 调 ledger 是模块之间的调用,不是系统边界。"只发生一次"由 schema.ts 的唯一约束管。
|
||||
// 提交内容的字段归 submissions,该不该开下一个阶段归 flow。
|
||||
|
||||
@@ -16,14 +16,18 @@ export interface WriteState {
|
||||
runStarted(run: string): boolean;
|
||||
/** 这一轮有没有消融格的运行已经确认启动。 */
|
||||
ablationStarted(round: number): boolean;
|
||||
/** 这一轮的诊断运行有没有已经确认启动。 */
|
||||
diagnosisStarted(round: number): boolean;
|
||||
}
|
||||
|
||||
/** 实现和核验阶段的提交不能替换(方法.md 第五部分总原则):实现、修复、核验、消融实现、消融核验。 */
|
||||
/** 实现和核验阶段的提交不能替换(方法.md 第五部分总原则):实现、修复、核验、消融实现、消融核验、诊断实现(含修复)、诊断核验。 */
|
||||
const NOT_REPLACEABLE: ReadonlySet<Stage> = new Set([
|
||||
"implementation",
|
||||
"verification",
|
||||
"ablationImplementation",
|
||||
"ablationVerification",
|
||||
"diagnosisImplementation",
|
||||
"diagnosisVerification",
|
||||
]);
|
||||
|
||||
export function checkWrite(kind: Kind, content: unknown, state: WriteState): void {
|
||||
@@ -35,7 +39,7 @@ export function checkWrite(kind: Kind, content: unknown, state: WriteState): voi
|
||||
/**
|
||||
* 第 1 条:只收开着的阶段的提交,即有开阶段记录、没有关阶段记录。
|
||||
* 第 2 条:新的一版必须正好接在本人在这个阶段、对同一个对象的最新一版后面(第一版是 1);
|
||||
* 实现、修复、核验、消融实现、消融核验只能交第一版。
|
||||
* 实现、修复、核验、消融实现、消融核验、诊断实现、诊断修复、诊断核验只能交第一版。
|
||||
*/
|
||||
function checkSubmission(s: Content<"submission">, state: WriteState): void {
|
||||
const where = `提交 ${s.kind}(阶段 ${s.stageId},作者 ${s.author},对象 ${s.target ?? "无"},编号 ${s.item ?? "无"},第 ${s.version} 版)`;
|
||||
@@ -63,7 +67,10 @@ function checkRunResult(r: Content<"runResult">, state: WriteState): void {
|
||||
}
|
||||
}
|
||||
|
||||
/** 第 4 条:这一轮已经有消融格确认启动了,就不能再关解释阶段(方法.md 4.3 ⑭:解释冻结必须早于任何一格启动)。 */
|
||||
/**
|
||||
* 第 4 条:这一轮已经有消融格确认启动了,就不能再关解释阶段(方法.md 4.3 ⑭:解释冻结必须早于任何一格启动)。
|
||||
* 第 5 条:这一轮的诊断运行已经确认启动了,就不能再关诊断预测阶段(方法.md 4.3 诊 2:冻结必须早于诊断运行启动,范围才算事前预测)。
|
||||
*/
|
||||
function checkStageClose(c: Content<"stageClose">, state: WriteState): void {
|
||||
const open = state.stageOpen(c.stageId);
|
||||
if (open?.content.stage === "explanation" && state.ablationStarted(open.content.round)) {
|
||||
@@ -71,4 +78,9 @@ function checkStageClose(c: Content<"stageClose">, state: WriteState): void {
|
||||
`不能关解释阶段 ${c.stageId}:第 ${open.content.round} 轮已经有消融格确认启动,解释冻结必须早于任何一格启动(方法.md 4.3 ⑭)`,
|
||||
);
|
||||
}
|
||||
if (open?.content.stage === "diagnosisPrediction" && state.diagnosisStarted(open.content.round)) {
|
||||
throw new Error(
|
||||
`不能关诊断预测阶段 ${c.stageId}:第 ${open.content.round} 轮的诊断运行已经确认启动,诊断预测冻结必须早于诊断运行启动(方法.md 4.3 诊 2)`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { DatabaseSync } from "node:sqlite";
|
||||
// 账本的表结构(docs/结构.md 第四部分"全部只追加"):只有一张表,每一行是序号、种类、内容、内容的哈希。
|
||||
// 表结构一改就把版本号加 1;旧文件版本号对不上时打开报错,不迁移,也不逐字核对建表语句。
|
||||
|
||||
export const SCHEMA_VERSION = 4;
|
||||
export const SCHEMA_VERSION = 5;
|
||||
|
||||
/** 新文件要执行的建表语句,由 Ledger 在一个事务里执行,最后写入版本号。 */
|
||||
export const CREATE_SCHEMA = [
|
||||
@@ -33,6 +33,8 @@ export const CREATE_SCHEMA = [
|
||||
`CREATE UNIQUE INDEX call_ended_once ON records (json_extract(content, '$.call')) WHERE kind = 'callEnded'`,
|
||||
// 结算以轮次为编号:每轮最多采纳一个改法,所以最多一次消融。
|
||||
`CREATE UNIQUE INDEX settlement_once ON records (json_extract(content, '$.round')) WHERE kind = 'settlement'`,
|
||||
// 诊断结算同样以轮次为编号:每轮最多一次诊断。
|
||||
`CREATE UNIQUE INDEX diagnosis_settlement_once ON records (json_extract(content, '$.round')) WHERE kind = 'diagnosisSettlement'`,
|
||||
`PRAGMA user_version=${SCHEMA_VERSION}`,
|
||||
];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user