feat: 任务书 10,submissions 模块与 materials 修改

- 新增 src/submissions:先程序检查(14 条跨字段规则、不许改的文件、代码存不了、指标编号占用、提案数上限),全过再问 Jev;退回原因列出该写的全部编号;回应/统一拼冻结协议主体只在这一处;核验、消融核验通过没有。
- materials:挑刺单写"现在交什么";退回按阶段、作者、种类、对象找(ledger 退回记录加 target,表结构版本 4);核验材料去掉 Jev 预扫;信念本写合法化;删"本该关着";消融核验不通过可重做,不跑的格从 cellNotRun 事件读原因。
- 用户 2026-10-03 定:冻结协议去掉 replies、replyBody,第二次预测的答复从已公开的回应或统一读;takenMetricIds 加两个保留键;解释一律交 cells;Jev 退回只列判"是"的几问、用英文问题名。
- jev 判重材料带 keySettings;读代码工具删 offset;三处旧说法改正。
- 文档:结构.md 第四、七、八部分,WORK_LOG。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-03 06:08:34 -04:00
parent a0ee4ef7a2
commit 09c44031a0
34 changed files with 1221 additions and 169 deletions
+12 -12
View File
@@ -223,27 +223,27 @@ test("读代码:目录里的文件和目录读得到;目录外的读不到
symlinkSync(secret, join(root, "link-dir"));
symlinkSync(join(secret, "proposal.md"), join(root, "link-file"));
assert.equal(readSource([root], join(root, "src", "a.py"), 1), "line1\nline2\n");
assert.equal(readSource([root], root, 1), "link-dir\nlink-file\nsrc/");
assert.equal(readSource([root], join(root, "src", "a.py")), "line1\nline2\n");
assert.equal(readSource([root], root), "link-dir\nlink-file\nsrc/");
for (const path of [base, secret, join(secret, "proposal.md"), join(root, "..", "other-researcher", "proposal.md"), join(root, "link-dir"), join(root, "link-file"), join(root, "link-dir", "proposal.md")]) {
assert.throws(() => readSource([root], path, 1), /不在可读的目录里/, path);
assert.throws(() => readSource([root], path), /不在可读的目录里/, path);
}
assert.throws(() => readSource([root], "src/a.py", 1), /只接受绝对路径/);
assert.throws(() => readSource([root], "src/a.py"), /只接受绝对路径/);
// 前缀相同但不是子目录的也不算在里面。
mkdirSync(`${root}-copy`);
assert.throws(() => readSource([root], `${root}-copy`, 1), /不在可读的目录里/);
assert.throws(() => readSource([root], `${root}-copy`), /不在可读的目录里/);
});
test("读代码:超过单次上限时分段,并写明从第几行接着读", (t) => {
test("读代码:超过单次上限时只显示前 2000 行,并写明截断", (t) => {
const root = realpathSync(tempDir(t, "page"));
const lines = Array.from({ length: 2500 }, (_, i) => `第 ${i + 1} 行`);
writeFileSync(join(root, "big.txt"), lines.join("\n"));
const first = readSource([root], join(root, "big.txt"), 1);
assert.ok(first.startsWith("第 1 行\n"));
assert.match(first, /本次显示第 1–2000 行[\s\S]*用 offset=2001 再调一次/);
const second = readSource([root], join(root, "big.txt"), 2001);
assert.match(second, /^第 2001 行\n/);
assert.match(second, /本次显示第 2001–2500 行[\s\S]*已读到结尾/);
const shown = readSource([root], join(root, "big.txt"));
assert.ok(shown.startsWith("第 1 行\n"));
assert.ok(shown.includes("第 2000 行\n"));
assert.ok(!shown.includes("第 2001 行"));
assert.match(shown, /截断:只显示了前 2000 行[\s\S]*共 2500 行/);
assert.ok(!shown.includes("offset"));
});
// ---------------------------------------------------------------------------