feat: 研究编号只许小写、配置路径必须绝对;检验判重两个顺序取平均
任务书 13 第一部分,用户 2026-10-03 同意。 - config:studyId 限定小写字母、数字和 ._-;task、promptDir 必须以 / 开头。 - eval:research.json 路径改绝对,writeConfig 不再转换;quality.ts 第 2、6 问每对 A、B 与 B、A 各问一次取平均,两次原始概率都存。 - tests:大写编号、相对路径各加测试。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+7
-1
@@ -19,6 +19,12 @@ const TYPE_TEXT: Readonly<Record<string, string>> = {
|
||||
null: "null",
|
||||
};
|
||||
|
||||
/** schema.ts 里文字字段、路径字段的格式,换成人读得懂的话。 */
|
||||
const PATTERN_TEXT: Readonly<Record<string, string>> = {
|
||||
"\\S": "不能为空,也不能只有空白",
|
||||
"^/": "必须是绝对路径(以 / 开头)",
|
||||
};
|
||||
|
||||
function reasonOf(e: SchemaError): string {
|
||||
const p = e.params as Record<string, unknown>;
|
||||
switch (e.keyword) {
|
||||
@@ -39,7 +45,7 @@ function reasonOf(e: SchemaError): string {
|
||||
case "minItems":
|
||||
return `至少要有 ${String(p.limit)} 项`;
|
||||
case "pattern":
|
||||
return p.pattern === "\\S" ? "不能为空,也不能只有空白" : `格式不对,应符合 ${String(p.pattern)}`;
|
||||
return PATTERN_TEXT[String(p.pattern)] ?? `格式不对,应符合 ${String(p.pattern)}`;
|
||||
default:
|
||||
return e.message;
|
||||
}
|
||||
|
||||
+17
-4
@@ -1,6 +1,5 @@
|
||||
import { Type, type Static, type TSchema } from "typebox";
|
||||
import { BATCH_RULES, CELL_RULES, type BatchRuleName, type CellRuleName } from "../rules/index.ts";
|
||||
import { Id } from "../vocab/index.ts";
|
||||
|
||||
// research.json 的字段定义(docs/结构.md 第二部分、第五部分"方法参数""步骤开关")。
|
||||
// 每个字段都必填,不写默认值;不认识的字段报错。可以没有的值写 null(目前没有这样的字段)。
|
||||
@@ -15,6 +14,11 @@ export type FieldCategory = (typeof FIELD_CATEGORIES)[number];
|
||||
const CLOSED = { additionalProperties: false } as const;
|
||||
/** 文字字段:不能为空,也不能只有空白。 */
|
||||
const TEXT = { pattern: "\\S" };
|
||||
/**
|
||||
* 路径字段必须是绝对路径:从别的目录接着跑一份研究时,相对路径会读到别处,而任务目录没有哈希核对挡着
|
||||
* (任务书 13 第一部分第 2 条)。
|
||||
*/
|
||||
const ABSOLUTE_PATH = { pattern: "^/" };
|
||||
|
||||
function user<T extends TSchema>(schema: T, description: string): T {
|
||||
return { ...schema, description, category: "用户配置" };
|
||||
@@ -127,8 +131,14 @@ const PositiveInteger = Type.Integer({ minimum: 1 });
|
||||
|
||||
export const ResearchConfig = Type.Object(
|
||||
{
|
||||
studyId: user(Id, "研究编号:决定的种子由它和轮次、版本算出;只许字母、数字和 ._-,首字符是字母或数字"),
|
||||
task: user(Type.String(TEXT), "用哪个任务:任务目录的路径。指标、方向、ε、时限等任务事实写在任务目录里"),
|
||||
studyId: user(
|
||||
Type.String({ pattern: "^[a-z0-9][a-z0-9._-]{0,127}$" }),
|
||||
"研究编号:决定的种子由它和轮次、版本算出,Docker 镜像名也带它,所以只许小写字母、数字和 ._-,首字符是小写字母或数字",
|
||||
),
|
||||
task: user(
|
||||
Type.String(ABSOLUTE_PATH),
|
||||
"用哪个任务:任务目录的绝对路径。指标、方向、ε、时限等任务事实写在任务目录里",
|
||||
),
|
||||
models: user(
|
||||
Type.Object(
|
||||
{
|
||||
@@ -172,7 +182,10 @@ export const ResearchConfig = Type.Object(
|
||||
),
|
||||
"轻量检查的次数与时长上限:只用来检查语法、接口和极小的样例,不能借它跑正式规模的求解",
|
||||
),
|
||||
promptDir: method(Type.String(TEXT), "提示词目录:各角色的角色提示词和各类任务消息放在这里"),
|
||||
promptDir: method(
|
||||
Type.String(ABSOLUTE_PATH),
|
||||
"提示词目录的绝对路径:各角色的角色提示词和各类任务消息放在这里",
|
||||
),
|
||||
devEntry: method(
|
||||
Type.Boolean(),
|
||||
"开发入口(方法.md 第九部分):正式研究写 false;开发调试时才写 true,打开过的研究不能当验收证据",
|
||||
|
||||
Reference in New Issue
Block a user