Files
InfoRSI/src/vocab/submissions.ts
T
iomgaa 852600df02 feat: 诊断(任务书 18 第一块):诊断数学、四种提交、一次运行跑多个实验、账本与材料、flow 诊断各步
消融默认关,关掉时解释阶段一并跳过;选诊断实验用信息价值减成本。
eval/diagnosis/research.json 为第三块配置。vocab 字段说明的出口文字随提示词一起改,见下一次提交的 prompts/ 与同文件改动(本次含在内)。

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 10:36:20 -04:00

776 lines
29 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Type, type Static, type TSchema } from "typebox";
import { Id } from "./basics.ts";
import type { SubmissionKind } from "./roster.ts";
import { HypothesisMetric } from "./runs.ts";
/**
* 每种提交的字段定义(方法.md 第五部分)。同一份定义同时是类型、收件时的格式检查、
* 发给模型的提交工具参数,所以字段说明写给模型看,每个字段都写明出口。
* 这里只管单个字段长什么样;跨字段的规则(q₁ < q₅ < q₉ 严格递增、因子数上限、覆盖是否齐全等)
* 在 submissions 模块。
* 程序分配的编号(候选、挑刺、入口编号)不让模型填;因子、实现条款的编号就是它在清单里的位置。
*/
/** 文字字段:不能为空,也不能只有空白。 */
const TEXT = { pattern: "\\S" };
/** 不认识的字段一律不收。 */
const CLOSED = { additionalProperties: false } as const;
// ---------------------------------------------------------------------------
// 共用字段
// ---------------------------------------------------------------------------
/** 三个数:一个分数的事前判断(方法.md 第二部分"范围")。 */
export const Range = Type.Object(
{
q1: Type.Number({ description: "有一成可能低于这个数" }),
q5: Type.Number({ description: "有一半可能低于这个数" }),
q9: Type.Number({ description: "有九成可能低于这个数" }),
},
{
...CLOSED,
description:
"三个数,按分数原值写,不管越大越好还是越小越好。必须严格递增 q1 < q5 < q9,认为几乎不变就写一个很窄的范围。" +
"没有\"不知道\"这个选项:拿不准就把 q1 和 q9 拉开",
},
);
export type Range = Static<typeof Range>;
const FactorKey = Type.String({
pattern: "^p[1-9][0-9]*$",
description: "因子编号:它在冻结协议因子清单里的位置,第 1 个是 p1",
});
const SafeguardName = Type.String({
pattern: "^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$",
description:
"保障短名:字母、数字和 ._-。不能叫 main,也不能写成 p1、p2 这种因子编号的样子," +
"因为答案路径里 main、因子编号和保障短名放在一起;位置表也按它对号",
});
const ClauseKey = Type.String({
pattern: "^c[1-9][0-9]*$",
description: "实现条款编号:它在冻结协议实现条款里的位置,第 1 条是 c1",
});
const CodeLocation = Type.String({
pattern: "^[^:\\s]+(:[1-9][0-9]*(-[1-9][0-9]*)?)?$",
description: "代码位置:\"文件\"、\"文件:行号\"或\"文件:起-止\",行号以本次提交代码为准。一个值只写一个连续范围,不带括号标签;多处位置拆开写",
});
const CONCERNS = Type.String({
...TEXT,
description:
"照冻结原文实现、但你认为会出问题的地方,尤其是某条保障会挡掉或改变什么。" +
"它会转给研究者,不阻止运行,也不改动协议。没有就写\"无\"",
});
// ---------------------------------------------------------------------------
// 第零轮:入口、讨论、志愿(方法.md 4.2)
// ---------------------------------------------------------------------------
const Entry = Type.Object(
{
name: Type.String({
...TEXT,
description: "名称:离开这份清单单独看也读得懂",
}),
body: Type.String({
...TEXT,
description:
"Markdown:从哪里开始看(先读哪段代码、先问哪个问题、先质疑哪个设定)、为什么值得有人去走。" +
"只写起点,不写\"应该改成什么、能到多少分\"",
}),
},
CLOSED,
);
const ENTRIES = Type.Array(Entry, {
minItems: 2,
maxItems: 3,
description: "2–3 个入口,彼此尽量不重叠;想不出第三个就交两个。编号由程序按顺序分配",
});
export const EntrySubmission = Type.Object(
{
entries: ENTRIES,
},
CLOSED,
);
export const DiscussionSubmission = Type.Object(
{
body: Type.String({
...TEXT,
description:
"讨论正文,Markdown。目标是分工,不是达成共识:哪些入口其实是同一条路," +
"哪条路没人站但值得走,你自己想走哪条",
}),
entries: Type.Optional({
...ENTRIES,
description: "可选:整份替换你自己的入口清单(2–3 个)。不换就不交这个字段",
}),
},
CLOSED,
);
export const ClaimSubmission = Type.Object(
{
choices: Type.Array(Id, {
minItems: 1,
description:
"志愿:按你想走的先后排入口编号,照材料里列的写,可以排别人的入口;至少排材料里写明的个数",
}),
},
CLOSED,
);
// ---------------------------------------------------------------------------
// 提案(方法.md 4.3 ②、第五部分"提案")
// ---------------------------------------------------------------------------
const Factor = Type.Object(
{
name: Type.String({
...TEXT,
description: "名称:离开这份提案也读得懂",
}),
method: Type.String({
...TEXT,
description:
"做法:改什么、怎么改。配套设定(离开这个因子就没有意义的设定值)写在这里,跟着它一起开、一起关",
}),
keySettings: Type.String({
...TEXT,
description: "关键设定:决定这个因子效果的设定值,例如\"统计窗口 1000 次查找、每次最多删四分之一\";没有写\"无\"",
}),
offBehavior: Type.Optional(
Type.String({
...TEXT,
description: "关掉这个因子时换成什么。省略就回到基线在这件事上的做法",
}),
),
continues: Type.Union([Id, Type.Null()], {
description:
"延续信念本里的哪个因子:写它的因子编号。只用于同一个想法的新版本(换了设定、换了基线);" +
"受它启发想出来的新想法不算延续。新因子写 null",
}),
},
CLOSED,
);
const FACTORS = Type.Array(Factor, {
minItems: 1,
description:
"因子清单:每个因子是单独放到基线上也说得通的改动,编号就是位置(第 1 个是 p1)。" +
"只有一个因子就写一个;拿不准一处改动算因子还是保障,就算因子。" +
"超过因子数上限时把多出来的留到下一轮,不要几个捆成一个",
});
const SAFEGUARDS = Type.Array(SafeguardName, {
description:
"保障清单,每条一个短名。保障在任何一格里都不改变评测打出来的分数,只在评测本来不收的情形下动手," +
"动手时只修到刚好合法、退回基线做法或直接报错;做不到的、拿不准的都是因子。没有保障交空数组",
});
const METRICS = Type.Object(
{
defined: Type.Array(HypothesisMetric, {
description: "新登记的假设专用指标,编号只写短名;没有就交空数组",
}),
reused: Type.Array(Id, {
description:
"引用已登记的假设专用指标,照材料里已登记指标清单的全名(\"候选编号.短名\")写;没有就交空数组。" +
"要测的量清单里已经有,就引用它,不换个名字重新登记:两个名字测同一个东西,会被当成两份独立的证据",
}),
},
{
...CLOSED,
description:
"指标登记:这个候选要采集哪些假设专用指标。最终指标和常规辅助指标程序每次都会采集,不用在这里写。" +
"假设专用指标由候选代码在运行当中算出,候选代码拿不到基线的成绩,\"比基线好多少\"这类量测不到。" +
"协议在某种情形下会让某个指标写 null(例如某条分支没走到、某个因子被关掉),就别给它选 invalidateRun,否则那次正式运行白跑",
},
);
const PROPOSAL_BODY = Type.String({
...TEXT,
description:
"提案正文,Markdown,带小标题:每个因子为什么可能有效;" +
"每条保障做什么、属于拦 / 补 / 改哪一种、自检时怎么想的;" +
"协议(不许改什么、随机性怎么处理、何时停、什么样的运行不算数);因子之间的关系。" +
"某方面不适用写\"不适用:原因\"。协议里不要求实验员按正式规模运行程序来核对什么,正式规模只由程序跑。" +
"不写自己估的分数或提升量;引用已测到的分数要写明出自哪次运行;" +
"文献和别人报告的数值只当起点,说明与本任务的区别;从第 2 轮起说明哪些新的观测影响了这条提案",
});
export const ProposalSubmission = Type.Object(
{
factors: FACTORS,
safeguards: SAFEGUARDS,
metrics: METRICS,
authorEstimate: Range,
body: PROPOSAL_BODY,
},
{
...CLOSED,
description:
"一条提案。authorEstimate 是你自己估的这个改法跑出来的最终指标,交上来就封存," +
"到本轮结束前不给任何人看。交不出合格提案时不要凑,在回复里写清卡在哪里",
},
);
// ---------------------------------------------------------------------------
// 两次预测、挑刺(方法.md 4.3 ④⑤⑦)
// ---------------------------------------------------------------------------
/** 第一次、第二次预测用同一个定义:对一个候选的最终指标给三个数。 */
export const PredictionSubmission = Type.Object(
{
range: Range,
body: Type.String({
...TEXT,
description:
"理由,Markdown:参照了什么,这一个和参照差在哪、所以往哪边挪;" +
"同一阶段你给别的候选的数和这一个相同或不同,差别出在机制的哪里",
}),
},
{
...CLOSED,
description: "对这个候选跑出来的最终指标给三个数",
},
);
export const CritiqueSubmission = Type.Object(
{
target: Type.String({
pattern: "^(whole|p[1-9][0-9]*)$",
description: "针对谁:整条提案写 whole,针对某个因子写它的编号(p1、p2……)",
}),
body: Type.String({
...TEXT,
description:
"挑刺内容,Markdown。每条意见写清是什么、在哪(能对照代码的写出位置)、不处理会怎样," +
"以及作者给出什么就能解决(不替作者选取值)。" +
"确实没找到问题,写查了什么、为什么认为没有",
}),
},
CLOSED,
);
// ---------------------------------------------------------------------------
// 回应与统一(方法.md 4.3 ⑥)
// ---------------------------------------------------------------------------
const REPLIES = Type.Array(
Type.Object(
{
critique: Type.String({
...Id,
description: "挑刺编号,照材料里列的写",
}),
reply: Type.String({
...TEXT,
description:
"先用一句复述这份挑刺说的是什么(照原意,不答弱化的版本),再给采纳、部分采纳或不采纳。" +
"采纳的说出改在改动的哪一项、哪一条条款,只在答复里表态等于没改;不采纳的先摆证据(代码位置、运行编号、协议原文)再讲理由;" +
"部分采纳的说清另一部分为什么不改、还剩什么局限。一份挑刺里有几条意见,在这一条里逐条答",
}),
},
CLOSED,
),
{
description: "材料\"本任务要答复的挑刺\"里列出的每一份挑刺各答复一条;没有挑刺交空数组",
},
);
const CLAUSES = Type.Array(
Type.String({
...TEXT,
description:
"一条实现条款:实验员要做的一件事,写到不用猜就能实现。开头写位置:\"文件\"、\"文件:行号\"或\"文件:函数名\"," +
"只写一个行号或一个函数名、不写范围,文件和函数要在基线代码里真实存在",
}),
{
minItems: 1,
description:
"实现条款,编号就是位置(第 1 条是 c1)。实验员照它实现,核验员逐条对号。" +
"条款之间不矛盾;不改任务自带的评分和校验程序,不改最终指标的算法;不让实验员按正式规模运行程序来核对什么",
},
);
export const ResponseSubmission = Type.Object(
{
replies: REPLIES,
changes: Type.Object(
{
factors: Type.Optional(FACTORS),
safeguards: Type.Optional(SAFEGUARDS),
metrics: Type.Optional(METRICS),
body: Type.Optional(PROPOSAL_BODY),
},
{
...CLOSED,
description:
"改动了的部分:写上的一项整项替换原提案的对应部分,没写的沿用原提案。" +
"什么都没改就交空对象。作者自评不能改",
},
),
clauses: CLAUSES,
body: Type.String({
...TEXT,
description: "答复正文,Markdown:逐条答复之外要补充的话。没有挑刺、也没有要补充的,写\"无\"",
}),
},
CLOSED,
);
export const UnificationSubmission = Type.Object(
{
factors: FACTORS,
safeguards: SAFEGUARDS,
metrics: METRICS,
body: PROPOSAL_BODY,
replies: REPLIES,
clauses: CLAUSES,
sources: Type.Array(
Type.Object(
{
proposal: Type.String({
...Id,
description: "被合并的原提案编号,照材料里列的写",
}),
coverage: Type.String({
...TEXT,
description: "这份原提案在统一后的协议里哪里体现;没采纳的部分写明为什么",
}),
},
CLOSED,
),
{
minItems: 1,
description: "逐条写明每份原提案在哪里体现",
},
),
},
{
...CLOSED,
description:
"几条提案合成的候选,由你写成一份完整的冻结协议。只能用原提案和挑刺里有的改动,不能另加新改动",
},
);
// ---------------------------------------------------------------------------
// 实现、修复、核验(方法.md 4.3 ⑨)
// ---------------------------------------------------------------------------
const LOCATIONS = Type.Array(CodeLocation, { minItems: 1 });
/** 实现和修复用同一个定义。代码本身由程序从实验员的工作目录冻结,不作为字段交。 */
export const ImplementationSubmission = Type.Object(
{
factorLocations: Type.Array(
Type.Object(
{
factor: FactorKey,
locations: LOCATIONS,
},
CLOSED,
),
{
description:
"因子位置表:冻结协议里每个因子一项,列出本次代码中它实际所在的全部位置,不只列这次修复的部分。一处代码服务两个因子,两边都写",
},
),
safeguardLocations: Type.Array(
Type.Object(
{
safeguard: SafeguardName,
locations: LOCATIONS,
},
CLOSED,
),
{
description:
"保障位置表:每条保障一项,短名照冻结清单写,位置以本次代码为准。同一行既属于因子又属于保障时,两边都写。冻结协议没有保障就交空数组",
},
),
unassigned: Type.Array(
Type.Object(
{
location: CodeLocation,
note: Type.String({
...TEXT,
description: "为什么不属于任何因子或保障,一句说明",
}),
},
CLOSED,
),
{
description: "不属于任何因子或保障的改动,按本次代码相对本批基线的完整差异列出,并说明服务哪项要求;没有就交空数组",
},
),
concerns: CONCERNS,
body: Type.String({
...TEXT,
description: "实现说明,Markdown:位置表之外需要说明的事。修复时逐条回应退回意见:改在哪里,或以协议原文和代码位置说明为什么不改。协议要求自行求解核数而未执行的,说明数值留给正式实验核对,不声称已经验证。没有要补充的就写\"无\"",
}),
},
CLOSED,
);
const FOUND = Type.Boolean({
description: "找到代码且实际行为符合该项要求写 true;找不到、找到但不一致或材料不足以核清,写 false(记为没落实)",
});
const WHERE = Type.String({
...TEXT,
description: "代码位置和足以复核的依据,对应冻结要求。没落实时区分具体偏差与核不了:写明看过哪里、哪里不符或还缺什么,不把猜测写成事实",
});
export const VerificationSubmission = Type.Object(
{
clauses: Type.Array(
Type.Object(
{
clause: ClauseKey,
found: FOUND,
where: WHERE,
},
CLOSED,
),
{
description: "每条实现条款一项",
},
),
factors: Type.Array(
Type.Object(
{
factor: FactorKey,
found: FOUND,
where: WHERE,
},
CLOSED,
),
{
description: "每个因子一项",
},
),
safeguards: Type.Array(
Type.Object(
{
safeguard: SafeguardName,
found: FOUND,
where: WHERE,
},
CLOSED,
),
{
description: "每条保障一项;冻结协议没有保障就交空数组",
},
),
unassigned: Type.Array(
Type.Object(
{
location: Type.String({
...CodeLocation,
description: "材料列出的改动块位置,逐字照抄位置本身,不带展示用的括号标签,不合并不同改动块",
}),
outOfScope: Type.Boolean({
description: "超出冻结协议、改了最终指标的测量或校验、未按登记定义采集或用占位数掩盖缺测,写 true;落实冻结要求所需的辅助代码写 false",
}),
reason: Type.String({
...TEXT,
description: "指出该块代码及对应的冻结要求,说明它为什么必要或哪里超出要求",
}),
},
CLOSED,
),
{
description: "材料里列出的没有归属的改动,逐条判断是否越界;材料说没有就交空数组",
},
),
body: Type.String({
...TEXT,
description:
"说明,Markdown:逐项结果之外需要说明的事。材料里列出的同一行既属于因子又属于保障的地方,在这里各写一句提醒(只是提醒,不判越界)。" +
"没有要补充的就写\"无\"",
}),
},
{
...CLOSED,
description: "只交逐项结果,通过与否由程序推出:任何一项没落实或判为越界,就退回实验员修复",
},
);
// ---------------------------------------------------------------------------
// 诊断:解释与实验、预测、实现、核验(方法.md 4.3 诊 1–诊 4、第五部分"诊断"三行)
// ---------------------------------------------------------------------------
const DiagnosisExplanation = Type.Object(
{
body: Type.String({
...TEXT,
description:
"Markdown:为什么卡在这里,剩下的空间在哪,什么样的实测会推翻它(写不出推翻它的实测,说明这条解释还不能被检验,先改具体再交)。" +
"诊断问的是剩下的空间在哪,不是上一步的功劳怎么分。没有具体判断就直说,写明查了什么、为什么拿不准",
}),
},
CLOSED,
);
const DiagnosisExperiment = Type.Object(
{
name: Type.String({
...TEXT,
description: "名称:离开这份清单单独看也读得懂",
}),
spot: Type.String({
...TEXT,
description: "动哪一处:在当前基线的哪一处代码或哪一步上动手,只写一处(文件、函数或步骤名),其余照基线保留;想测两处就拆成两个实验",
}),
body: Type.String({
...TEXT,
description:
"Markdown:在这一处怎么动(换成明显更强的版本、换成另一种做法、拿掉,或放宽某个限制)、" +
"做完交出什么能判分的答案、几种可能的结果各排除哪几条解释(有分不开的也写明)。不写自己估的分数,分数在下一步交",
}),
metrics: Type.Array(HypothesisMetric, {
description:
"登记假设专用指标:这个实验的代码要额外记录的量,编号只写短名;没有就交空数组。" +
"诊断实验里的指标只能选 recordMissing(缺了只记缺失),选 invalidateRun 会被退回",
}),
},
CLOSED,
);
export const DiagnosisProposalSubmission = Type.Object(
{
explanations: Type.Array(DiagnosisExplanation, {
minItems: 1,
description: "诊断解释清单,编号由程序分配;条数上限见材料。真有第二个看法再写第二条,各条之间要真的不同;没有具体判断,就写一条直说没有的",
}),
experiments: Type.Array(DiagnosisExperiment, {
minItems: 1,
description:
"诊断实验清单,个数上限见材料。好的实验是不同解释对它的预测差得远:大家都预测涨不了多少的实验,测了也不改变下一步。" +
"每个实验只动一处,用时要放得进分到的那份时间;想不出能把解释分开的实验,就交最能暴露你的解释错在哪的那个",
}),
},
{
...CLOSED,
description: "对当前基线的诊断:几条解释,和能把它们分开的几个实验。实验正文里不写自己估的分数",
},
);
export const DiagnosisPredictionSubmission = Type.Object(
{
predictions: Type.Array(
Type.Object(
{
explanation: Type.String({ ...Id, description: "你自己的诊断解释编号,照材料里列的写" }),
experiment: Type.String({ ...Id, description: "合并后的诊断实验编号,照材料里列的写,别人提的也要给" }),
range: Range,
},
CLOSED,
),
{
description:
"你自己的每条诊断解释对每个合并后的实验各给三个数:按这条解释,做了这个实验,分数有一成、一半、九成可能低于多少。" +
"不多不少,每一对只写一次;按这条解释本身写,不往折中的范围靠;解释和这个实验没关系就按基线附近写并放宽;拿不准就把 q1 和 q9 拉开",
},
),
body: Type.String({
...TEXT,
description: "理由,Markdown:这些数是怎么来的,不同解释给的数差在哪里;几条解释给的数差不多,写明它们在这些实验上分不开",
}),
},
CLOSED,
);
/** 诊断实现和修复用同一个定义。代码本身由程序从实验员的工作目录冻结,不作为字段交。 */
export const DiagnosisImplementationSubmission = Type.Object(
{
locations: Type.Array(
Type.Object(
{
experiment: Type.String({ ...Id, description: "诊断实验编号,照材料里列的写" }),
locations: LOCATIONS,
},
CLOSED,
),
{
description: "位置表:选中的每个实验一项,列出本次代码中这个实验实际所在的全部位置,行号以本次提交代码为准",
},
),
concerns: CONCERNS,
body: Type.String({
...TEXT,
description: "实现说明,Markdown:位置表之外需要说明的事;实验原文没规定规模时,写你选了什么、为什么放得进分到的时间。修复时逐条回应核验意见:改在哪里,或以实验原文和代码位置说明为什么不改。没有要补充的就写\"无\"",
}),
},
CLOSED,
);
export const DiagnosisVerificationSubmission = Type.Object(
{
experiments: Type.Array(
Type.Object(
{
experiment: Type.String({ ...Id, description: "诊断实验编号,照材料里列的写" }),
followed: Type.Boolean({
description: "照实验写的做法实现了写 true;没找到、做得不一样或材料不足以核清,写 false",
}),
nothingElse: Type.Boolean({
description: "没有动实验写的那一处以外的地方写 true;顺手改了别处(含顺手改进)写 false",
}),
where: WHERE,
},
CLOSED,
),
{
description: "选中的每个实验一项,逐个判断,一个实验不通过不影响别的实验",
},
),
body: Type.String({
...TEXT,
description: "说明,Markdown:逐项结果之外需要说明的事。没有要补充的就写\"无\"",
}),
},
{
...CLOSED,
description: "只交逐个实验的结果,通过与否由程序推出:任何一项写 false 的实验退回实验员修复,用完修复次数仍不通过的实验从这次诊断里拿掉",
},
);
// ---------------------------------------------------------------------------
// 解释、消融、收尾(方法.md 4.3 ⑭⑯⑱)
// ---------------------------------------------------------------------------
const Explanation = Type.Object(
{
body: Type.String({
...TEXT,
description:
"Markdown:机制是什么、哪个因子在出力、什么情况下不成立、因子之间在效果上怎么互相依赖" +
"(例如\"没有 p2,p3 就没用\",当作预测交给消融检验)、结论覆盖哪些设定、没覆盖哪些。" +
"没有具体的机制判断就直说",
}),
cells: Type.Optional(
Type.Array(
Type.Object(
{
factor: FactorKey,
range: Range,
},
CLOSED,
),
{
description:
"每一格三个数:假如这条解释是对的,关掉这个因子后最终指标的范围。" +
"材料说要给每格的数时(开着消融),材料里列出的每一格都要有;" +
"没有具体的机制判断时,照实把范围写宽。材料说不给每格的数时(关掉了消融),不交这个字段",
},
),
),
},
CLOSED,
);
export const ExplanationSubmission = Type.Object(
{
explanations: Type.Array(Explanation, {
minItems: 1,
description: "一般交一条就够,真有第二个机制判断时再交第二条——比如你的主判断若错了最可能是哪种错法,答得出来就写成第二条,写明哪一格能把两条分开;条数上限见材料",
}),
},
CLOSED,
);
export const AblationImplementationSubmission = Type.Object(
{
alsoOff: Type.Array(FactorKey, {
description:
"需要一起关的因子:只有关掉指定因子后代码真的跑不起来、必须连带关掉别的因子时才写。" +
"只关指定因子就交空数组",
}),
cannotRun: Type.Union([Type.Null(), Type.String(TEXT)], {
description:
"这一格跑不起来、也给不出一起关的方案时写原因,这一格不启动、不扣次数。跑得起来写 null",
}),
concerns: CONCERNS,
},
{
...CLOSED,
description: "从完整代码出发,把指定的因子换回关掉时的做法,其余因子和全部保障照留",
},
);
export const AblationVerificationSubmission = Type.Object(
{
factors: Type.Array(
Type.Object(
{
factor: FactorKey,
off: Type.Boolean({
description: "这份代码里这个因子是关着的写 true,照完整版本保留写 false",
}),
where: Type.String({
...TEXT,
description: "依据:在哪几行看到的。不属于任何单个因子的总体核对说明(怎么核的、行号怎么对上的),写进被关掉因子那一项的依据里",
}),
},
CLOSED,
),
{
description: "冻结协议里每个因子一项",
},
),
},
{
...CLOSED,
description: "只查一件事:是不是只关了指定的因子",
},
);
export const WrapUpSubmission = Type.Object(
{
body: Type.String({
...TEXT,
description:
"收尾,Markdown:什么被支持了、什么被挑战了、下一步想往哪走:沿某个因子继续,或换一条更可能拿最高分的路线。" +
"推广结论时写清它覆盖哪些设定。某方面没有写\"没有:为什么\"。" +
"原样放进下一轮的提案材料,所有人都读得到",
}),
},
CLOSED,
);
/** 每种提交用哪个字段定义,键与 roster.ts 的 SUBMISSION_KINDS 相同。 */
export const SUBMISSION_SCHEMAS = {
entry: EntrySubmission,
discussion: DiscussionSubmission,
claim: ClaimSubmission,
diagnosisProposal: DiagnosisProposalSubmission,
diagnosisPrediction: DiagnosisPredictionSubmission,
diagnosisImplementation: DiagnosisImplementationSubmission,
diagnosisRepair: DiagnosisImplementationSubmission,
diagnosisVerification: DiagnosisVerificationSubmission,
proposal: ProposalSubmission,
firstPrediction: PredictionSubmission,
critique: CritiqueSubmission,
response: ResponseSubmission,
unification: UnificationSubmission,
secondPrediction: PredictionSubmission,
implementation: ImplementationSubmission,
repair: ImplementationSubmission,
verification: VerificationSubmission,
explanation: ExplanationSubmission,
ablationImplementation: AblationImplementationSubmission,
ablationVerification: AblationVerificationSubmission,
wrapUp: WrapUpSubmission,
} as const satisfies Record<SubmissionKind, TSchema>;
/** 某种提交的内容类型,例如 Submission<"proposal">。 */
export type Submission<K extends SubmissionKind> = Static<(typeof SUBMISSION_SCHEMAS)[K]>;