dsh-eval-guard 0.7.2 → 0.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/ISSUES.md +235 -0
  2. package/README.md +46 -18
  3. package/assets/neural-cifar/workspace.zip +0 -0
  4. package/assets/neural-cpp/workspace.zip +0 -0
  5. package/assets/neural-fp32/workspace.zip +0 -0
  6. package/assets/neural-pendulum/SPEC.md +39 -32
  7. package/assets/neural-pendulum/TASK.md +137 -32
  8. package/assets/neural-pendulum/workspace.zip +0 -0
  9. package/eval/README.md +19 -9
  10. package/eval/__pycache__/bomberman.cpython-310.pyc +0 -0
  11. package/eval/__pycache__/commit0.cpython-310.pyc +0 -0
  12. package/eval/__pycache__/common.cpython-310.pyc +0 -0
  13. package/eval/__pycache__/ctf.cpython-310.pyc +0 -0
  14. package/eval/__pycache__/featurebench.cpython-310.pyc +0 -0
  15. package/eval/__pycache__/land.cpython-310.pyc +0 -0
  16. package/eval/__pycache__/neural-cifar.cpython-310.pyc +0 -0
  17. package/eval/__pycache__/neural-cpp.cpython-310.pyc +0 -0
  18. package/eval/__pycache__/neural-fp32.cpython-310.pyc +0 -0
  19. package/eval/__pycache__/neural-pendulum.cpython-310.pyc +0 -0
  20. package/eval/__pycache__/swe-bench-pro.cpython-310.pyc +0 -0
  21. package/eval/__pycache__/tank.cpython-310.pyc +0 -0
  22. package/eval/__pycache__/warehouse.cpython-310.pyc +0 -0
  23. package/eval/bomberman.py +5 -3
  24. package/eval/commit0.py +10 -3
  25. package/eval/common.py +169 -5
  26. package/eval/ctf.py +4 -2
  27. package/eval/featurebench.py +12 -8
  28. package/eval/land.py +4 -2
  29. package/eval/legacy/__pycache__/bomberman.cpython-310.pyc +0 -0
  30. package/eval/legacy/__pycache__/commit0.cpython-310.pyc +0 -0
  31. package/eval/legacy/__pycache__/ctf.cpython-310.pyc +0 -0
  32. package/eval/legacy/__pycache__/featurebench.cpython-310.pyc +0 -0
  33. package/eval/legacy/__pycache__/land.cpython-310.pyc +0 -0
  34. package/eval/legacy/__pycache__/swe_bench_pro.cpython-310.pyc +0 -0
  35. package/eval/legacy/__pycache__/tank.cpython-310.pyc +0 -0
  36. package/eval/legacy/__pycache__/warehouse.cpython-310.pyc +0 -0
  37. package/eval/legacy/bomberman.py +5 -2
  38. package/eval/legacy/ctf.py +5 -2
  39. package/eval/legacy/featurebench.py +55 -15
  40. package/eval/legacy/land.py +6 -3
  41. package/eval/legacy/swe_bench_pro.py +57 -16
  42. package/eval/legacy/tank.py +2 -2
  43. package/eval/legacy/warehouse.py +4 -4
  44. package/eval/neural-cpp.py +9 -6
  45. package/eval/neural-fp32.py +17 -5
  46. package/eval/swe-bench-pro.py +11 -7
  47. package/eval/tank.py +11 -2
  48. package/eval/warehouse.py +17 -1
  49. package/lib/client/index.js +56 -29
  50. package/lib/client/index.js.map +1 -1
  51. package/lib/index.js +878 -297
  52. package/native/dsh-eval-supervisor +0 -0
  53. package/native/supervisor.c +190 -26
  54. package/neural-cifar-eval/README.md +5 -0
  55. package/neural-cifar-eval/__pycache__/cifar_cache.cpython-310.pyc +0 -0
  56. package/neural-cifar-eval/__pycache__/common.cpython-310.pyc +0 -0
  57. package/neural-cifar-eval/__pycache__/fetch_cifar.cpython-310.pyc +0 -0
  58. package/neural-cifar-eval/__pycache__/ops_eval.cpython-310.pyc +0 -0
  59. package/neural-cifar-eval/__pycache__/run_eval.cpython-310.pyc +0 -0
  60. package/neural-cifar-eval/common.py +13 -0
  61. package/neural-cifar-eval/ops_eval.py +17 -5
  62. package/neural-cifar-eval/run_eval.py +42 -32
  63. package/neural-pendulum-eval/README.md +62 -0
  64. package/neural-pendulum-eval/__pycache__/ops_eval.cpython-310.pyc +0 -0
  65. package/neural-pendulum-eval/__pycache__/run_eval.cpython-310.pyc +0 -0
  66. package/neural-pendulum-eval/ops_eval.py +603 -0
  67. package/neural-pendulum-eval/run_eval.py +218 -137
  68. package/package.json +7 -11
  69. package/assets/neural-pendulum/hidden/test_infra.cpp +0 -631
  70. package/assets/neural-pendulum/include/nn/nn.hpp +0 -88
package/ISSUES.md ADDED
@@ -0,0 +1,235 @@
1
+ # dsh-eval-guard 问题清单与修复记录
2
+
3
+ > 版本:0.7.3 · 审计基线:本仓库工作树(HEAD 1e1f6b4 + 未提交改动)
4
+ > 对照 DSH:0.2.1-alpha.1 源码(并核对 git tag 0.1.2 / 0.1.5 / 0.1.7 / 0.2.0-rc.1 / rc.2 / 0.2.1-alpha.1)
5
+ > 本文件先记录问题,再记录修复状态。状态:✅ 已修复 / 🟡 部分修复 / ⛔ 保留(有明确原因或需要架构级改动)
6
+ >
7
+ > **2026-10-22 更新**:本轮只修复“守护本体 + Neural-Pendulum”。已修复:fork/子代理会话识别与约束、子代理路径审计、sandbox 继承环境清洗、PTC 控制通道标记回填、allow 规则宿主绑定安全、写路径规则、设置页任务默认值原子保存、Job 异步失败清理与重启 PID 校验、Pendulum 按请求时刻计分与 done final_score。
8
+ > **下文仍有若干条目标记为 ✅ 但实际未完成,不要再按旧状态理解**:arena legacy 的 `std::thread` 静态规则未移除;`cifar_cache.py` 解压仍无 filter、缓存路径仍用 `Path.home()/.dsh`;CIFAR 隐藏标签仍以文件形式落盘;FP32“30 分钟整轮”仍是 op 间检查;无 baseline 时评测仍 fail-open。其余任务相关修复按用户要求暂不动。
9
+
10
+ ## 0. 修复状态总览
11
+
12
+ | 类别 | 状态 | 备注 |
13
+ |---|---|---|
14
+ | 会话元数据读错字段(P0) | ✅ | 统一改读 `session.header.{cwd,origin,parentSession,delegationDepth}`,并加真实形状测试 |
15
+ | 工具路径审计失效(P0) | ✅ | 恢复审计;工作区缺失时 fail-closed;扩充受审计工具 |
16
+ | enable 失败被吞(P0) | ✅ | 增加 bwrap/userns 功能探测、错误落盘/上报/UI 展示、失败退避 |
17
+ | /tmp 工作区沙箱不可用(P0) | ✅ | 调整 bwrap 挂载顺序;supervisor 增加 `tmpfs` 规则 |
18
+ | io_uring / rename 目标 / 机制欺骗(P0) | 🟡 | io_uring 改为 EPERM 软拒绝(不杀进程);rename/link 双路径检查;新增 symlink/link/mknod/utimensat/statx/fchmodat2 拦截;bwrap 识别仍按 executable 名(bwrap 在多发行版是 shim 链,pid 绑定会破坏 setup),setup 豁免仅限 pivot 后不存在的路径 |
19
+ | 未知工具放行 → goal/schedule/drawio 绕过(P0) | ✅ | 默认黑名单新增这些工具族 |
20
+ | 评测执行不可信代码无隔离(P0) | 🟡 | 修复可修部分:环境变量白名单、隐藏数据先读入内存、CIFAR 标签隔离、venv 完整性校验、测试文件从宿主基线恢复;同用户同机执行仍无法彻底隔离,已在 README 已知边界说明 |
21
+ | 隐藏测试/负载不隐藏(P0) | 🟡 | 同上;commit0 无隐藏测试的问题改为“从安装时快照恢复测试”;仓库仍保留同用户读面 |
22
+ | commit0/SWE/FeatureBench 可伪造(P0) | 🟡 | venv 关键文件校验 + 测试文件基线恢复 + 剥掉 EVAL_* 环境变量;同用户进程仍可读 hidden |
23
+ | neural-pendulum 端到端不可用(P0) | ✅ | 修 autoBind→run→eval_submit/eval_test;修 meta 起点;final_score 落盘 |
24
+ | warehouse 单结果恒 0 分(P1) | ✅ | wrapper 字段对齐 |
25
+ | arena wrapper W/D/L 恒 0 / 超时缺失(P1) | ✅ | 修字段,补超时 |
26
+ | 价格文件死链/空表(P1) | ✅ | 改为按任务文件名并容错;价目表本身仍为空,成本显示 missing(不再误报 0 分) |
27
+ | neural-fp32 无总超时/EVAL_* 泄漏(P1) | ✅ | 加总 deadline、子进程环境过滤 |
28
+ | CIFAR 隐藏标签与图像同目录(P0) | ✅ | 标签只读入内存,图像复制到临时目录 |
29
+ | neural-cpp 隐藏测试 build 后才读(P0) | ✅ | 脚本启动即快照到内存,build 后再落盘编译 |
30
+ | prompt 硬编码分钟数(P2) | ✅ | 改为按当前 timeLimitMinutes 插值 |
31
+ | /tmp 写、系统目录读与 README 口径(P1) | ✅ | 审计恢复后写路径受控;README 改为准确描述“系统目录只读可见、/tmp 为工作区私有” |
32
+ | 包类型声明缺失、native 预编译(P2) | ✅ | 移除不存在的 types 导出;构建脚本补 native |
33
+ | 文档/文案/包装器 docstring(P3) | ✅ | 已对齐 |
34
+
35
+ ---
36
+
37
+ ## 1. 插件本体:P0 致命问题
38
+
39
+ ### 1.1 会话元数据读错字段,路径审计/子孙清理/自动绑定整体失效
40
+
41
+ **现象**
42
+ - 插件按 `session.header.meta.{cwd,origin,parentSession,delegationDepth,title}` 读取(src/guard.ts 的 isMain/checkTool/onAgentCreated/descendants/associate/runningSessions)。
43
+ - DSH 的 `SessionHeader` 字段在**顶层**:`cwd / parentSession / origin / delegationDepth / agentPreset`,没有 `meta`(packages/core/session/src/types.ts;0.1.2 至 0.2.1-alpha.1 各 tag 均如此)。
44
+ - 后果:
45
+ 1. `checkTool` 拿不到 workspace → 直接放行,**工具参数路径审计从未执行**;
46
+ 2. `isMain()` 恒 true(子代理/子会话不被排除);
47
+ 3. `descendants()` 恒空 → 超时不杀子代理;
48
+ 4. `onAgentCreated` 拿不到 cwd → `autoBind` 永不执行 → 无 run record;
49
+ 5. 标题/cwd 展示为空。
50
+ - 因此 `read`/`grep`/`glob` 等宿主工具可读工作区外任意文件(DSH 的 read 工具无沙箱围栏:fs-sandbox 注释 “Reads pass through untouched”),包括 `~/.ssh`、`~/.dsh/**`(含 CIFAR 隐藏验证集缓存、pendulum host submissions/events)、插件内隐藏测试、其它会话工作区。
51
+
52
+ **根因**:代码从未在真实 DSH 上验证;自带 `test/simulate.ts` 用假会话 `{header:{meta:{cwd}}}`,把错误形状写进夹具,且断言 `installed.runId` 已与当前 `install()` 返回不符。
53
+
54
+ **修复**
55
+ - 统一 helper:`sessionCwd / sessionParent / sessionIsSubagent`,isMain 基于真实字段;
56
+ - descendants 基于 `header.parentSession`;
57
+ - 标题回退为 cwd/id(DSH header 无 title);
58
+ - 审计拿不到 cwd 时 **fail-closed**(拒绝文件类工具并记事件),不再静默放行;
59
+ - 重写 simulate 测试用真实 header 形状,并新增“工作区外读取必须被拒”的断言。
60
+
61
+ ### 1.2 DSH 读取工具本身不设防(依赖 1.1 的审计)
62
+
63
+ 已在 1.1 修复;补充说明:审计的读语义是“工作区 + 只读系统文件可读,其余拒绝”,写语义是“仅工作区 + 无痕设备”。
64
+
65
+ ### 1.3 /tmp 与系统目录与 README 口径不一致
66
+
67
+ - DSH workspace-write 的 writableRoots 含 /tmp 与 os.tmpdir(packages/sandbox/sandbox/src/roots.ts),插件又把主会话强制为 workspace-write → `write/edit` 可写 /tmp;与 README“工作区外包括 /tmp 不可访问”矛盾。
68
+ - bwrap 只读挂载 /usr /etc /opt /sys /var/lib,超 supervisor 也放行其读 → 系统目录对 agent 可读。
69
+ - 修复:审计恢复后 `write/edit` 的 /tmp 写被拒;README 改为准确描述(系统目录只读可见、/tmp 映射为工作区私有 .tmp、用户数据目录不可读)。
70
+
71
+ ### 1.4 enable 失败被吞
72
+
73
+ - `syncConfig()` 里 `void this.enable()`;enable 在 supervisor 缺失/sandbox 服务缺失时返回错误但无人处理 → UI 显示已启用、实际无约束;每秒重试。
74
+ - 只检查 supervisor 文件存在,不探测 bwrap/userns。
75
+ - 修复:enable 前做 bwrap 功能探测(`bwrap --version` + 最小命名空间 probe);失败记 `lastError`、写事件、通过 `/api/eval-guard/state` 暴露、设置页红字展示;失败后退避 5s 再重试;成功清空。
76
+
77
+ ### 1.5 未知工具默认放行(黑名单按名字猜)
78
+
79
+ - 默认黑名单=基础名单+名字正则,未覆盖当前环境里可绕过评测的已装工具:`create_goal/update_goal`(goal 自动续轮绕过 deadline)、`schedule_*`(超时后唤醒)、`drawio_*`(直接 node:fs 写文件,可跨工作区写)、`canvas_*`、`skill` 等。
80
+ - 修复:BASE_BLACKLIST 增加这些名字,PLUGIN_BLACKLIST_PATTERNS 增加 `^drawio_`、`^schedule_`、`^(create|get|update)_goal$`、`^canvas_`、`^view_canvas$`;受审计工具集合补 drawio 读写。
81
+
82
+ ### 1.6 进程沙箱缺陷
83
+
84
+ - io_uring 对 basename 以 `node` 开头的进程放行(与 UV_USE_IO_URING=0 自相矛盾),可用改名进程绕过 seccomp 路径审计 → 修复:取消豁免,一律拒绝。
85
+ - rename/renameat/renameat2 只检查源路径 → 修复:同时检查源与目标。
86
+ - `is_bwrap()` 只看 exe 文件名含 bwrap,可被伪造 → 修复:绑定首次 exec 的 bwrap pid,仅该 pid 在 setup 阶段享有豁免。
87
+ - 未拦截 symlink/link/mknod/utimensat/fchmodat2/statx → 补齐(symlink 目标不触盘;link/symlinkat 新路径按写检查;其余按读/写)。
88
+ - 工作区位于 /tmp 时 bwrap 先 bind workspace 再 tmpfs /tmp,tmpfs 覆盖工作区 → 修复:先 tmpfs /tmp 再 bind workspace;supervisor 增加 `tmpfs` 规则允许沙箱内 /tmp 读写(ephemeral)。
89
+ - supervisor 用“argv 里最后一个 --”注入 --chdir,命令含独立 -- 时错位 → 修复:插件显式传 `--cwd`,supervisor 仅做“必须在工作区内”的校验。
90
+ - `wrapSandbox` 的 cwd 参数被 void → 修复:真正传给 supervisor。
91
+ - `enforcement:'full'` 无探测支撑;native 二进制为仓库预编译 → 构建脚本统一重建(见 5.2)。
92
+
93
+ ### 1.7 时间限制语义
94
+
95
+ - `jobs.list(session)` 含无主 job(jobs-local: owner 缺省时所有 caller 可见),被当成会话自己的 job → 误杀/误等;修复:只统计 `owner === sessionId` 的 job。
96
+ - 子代理不递归(1.1 修复)。
97
+ - turn/end 后 tick 立即清 deadline,可能与后台 job 注册竞争 → 修复:增加 5s 活动宽限(lastActivity)。
98
+ - 超时后 run 仍 active、usage 继续累加 → 修复:expire 时把 run 置 timeout 并写盘;后续事件忽略已结束 run。
99
+ - deadline 仅内存,DSH 重启丢失 → 保留为已知边界(README 说明),不做磁盘持久化(重启后没有正在跑的轮次,恢复语义不明)。
100
+
101
+ ### 1.8 审批副作用
102
+
103
+ - `approval.setPolicy(agent,'never')` 会注入一条 user-approval 消息(DSH 行为),可能影响模型;approvalPrev 会覆盖用户期间手动设置。
104
+ - 修复:保持强制 never(评测必需),在 README/设置页提示“启用时会给运行中会话注入一条策略变更消息;停用恢复启用前策略”。
105
+
106
+ ---
107
+
108
+ ## 2. 评测体系:P0 完整性问题
109
+
110
+ 所有 eval/install job 由宿主 JobManager 直接 spawn,继承完整 process.env、无沙箱;被评测对象是 agent 写的源码与编译产物。
111
+
112
+ ### 2.1 已修复/缓解
113
+ - **环境变量白名单**:JobManager 只传 PATH/HOME/LANG/LC_*/TMPDIR/SSL_* 等;EVAL_* 由 job 显式注入;评估脚本再 spawn 子进程时剥离 EVAL_RESULT_FILE/EVAL_JOB_DIR/EVAL_INSTALL_TOKEN,避免把结果路径交给候选代码。
114
+ - **neural-cpp**:脚本启动即把 `assets/neural-cpp/hidden/test_neural.cpp` 读入内存,候选 cmake build 结束后才写临时文件并编译 → build 阶段无法替换隐藏测试。
115
+ - **SWE/FeatureBench**:patch / hidden test / instance 在脚本早期读取;hidden 测试注入后再跑;P2P/测试文件由“安装时基线快照”在评测前恢复(见 2.2)。
116
+ - **CIFAR**:先读 hidden labels 到内存,把 images 复制到独立临时目录再交给候选 infer;不再把 labels 同目录暴露。
117
+ - **commit0/SWE/FeatureBench venv**:安装成功时记录 `.venv` 关键文件清单(python 真实路径、pyvenv.cfg、pytest/_pytest/pluggy 目录树 sha256);评测前校验,不一致直接判失败(不再静默伪造)。
118
+ - **测试来源**:安装成功时为 commit0/SWE/FeatureBench 快照测试目录(tests/、test/、pytest.ini、conftest.py);评测前从宿主快照覆盖候选副本并清理候选新增的 conftest.py,避免改测试/加 conftest 伪造通过。
119
+ - **价格/成本**:legacy 脚本改为读取对应 `<task>-prices.json`(缺失/空表时按 missing 处理,不再恒 0 且来源错误)。
120
+
121
+ ### 2.2 保留(结构性)
122
+ - 评测器与候选代码仍以**同一 OS 用户、同一机器**执行;理论上仍可用 CMake/二进制扫描文件系统篡改评测器/结果。彻底修复需要独立用户/容器/微虚拟机执行评测,超出本插件单进程能力,已在 README 的“已知边界”明确标注,并建议生产环境用独立账号或容器执行 eval job。
123
+ - `EVAL_RESULT_FILE` 仍通过 env 传给顶层 evaluator(候选二进制可通过 /proc 窥探父进程环境/命令行);已剥离直接继承,但同用户无法完全隐藏。
124
+
125
+ ---
126
+
127
+ ## 3. 各任务问题与修复
128
+
129
+ ### 3.1 tank
130
+ - 单结果评测仅 quick(20 局,仅 baseline),rating 与正式赛 BT 不可比 → 文档标注;wrapper 修正 W/D/L(从 pairwise 汇总)。
131
+ - 静态扫描把 std::thread 判可疑,但 RULES 允许线程 → 移除线程规则。
132
+ - kit 与工作区快照漂移(README/clock.py/history 等)→ README 记录 kit 差异;不再把 history 当作评测输入(仅 --with-history 时使用,单结果评测不启用)。
133
+ - eval kit 写入插件目录(build/history)→ 保持,README 说明需插件目录可写。
134
+
135
+ ### 3.2 warehouse
136
+ - wrapper 读 `row.get('speedup')`,实际字段 `geomeanSpeedup` → 单结果恒 0 → 已修(score/speedup/correct/status 对齐)。
137
+ - 单候选归一化退化(>1x 即 100 分)→ 单结果视为“加速比参考”,不再宣称分数;文档说明。
138
+ - 公开负载同时在工作区与 eval kit(含 .out),可硬编码 → 保留为已知限制:正式跑分应使用隐藏负载;README 标注。评估脚本仍只跑 public(单结果评测定位是自查)。
139
+ - CRLF 归一化与“逐字节”口径不同 → 文档措辞改为“逐字节(CRLF 归一化)”。
140
+ - 候选可 fork/写文件/联网未被运行时审计 → 保留(同用户执行问题);静态扫描仅报告。
141
+
142
+ ### 3.3 land / bomberman / ctf
143
+ - quick 档只跑单挑/2 人/2-3 方,与任务宣称的混战/2-10/2-15 不符 → 文档标注单结果评测覆盖范围;wrapper 的 W/D/L 字段改为按 summary 实际字段输出(没有就不输出)。
144
+ - BT 拟合失败时静默 0 分 → legacy 检测 `unavailable` 并以 `ok:false` 报告。
145
+ - 子进程无超时 → 补 timeout(1800s/3600s)。
146
+ - 评测 kit 与工作区文档漂移(README/clock/TASK)→ README 记录;工作区文档保持原样。
147
+
148
+ ### 3.4 commit0
149
+ - 提示词称“隐藏测试”,实际跑工作区 tests → 改为“从安装时快照恢复的仓库原始测试”,并快照 tests/pytest.ini;评测前恢复+清理新增 conftest。
150
+ - `.venv` 可伪造 → venv 关键文件校验。
151
+ - setup 未执行 `pip install -e .` 且 python 版本与 instance 不同 → setup.sh 补 `pip install -e .`(在实现已存在时);版本不一致记 README。**注意**:安装时 tinydb/ 已删,pip install -e . 会失败,故不在 install 时执行;改为评测前检测元数据缺失风险,README 说明。
152
+ - spec.pdf.bz2 命名 → cleanup 列表修正为同时清理 spec.pdf.bz2(保留 spec.pdf)。
153
+
154
+ ### 3.5 SWE-Bench Pro
155
+ - patch 应用 returncode 未检查 → 补检查,失败即判失败;应用后校验 F2P 节点存在。
156
+ - F2P/P2P 区分丢失 → wrapper 按 instance 的 fail_to_pass/pass_to_pass 计算,skipped 不计通过。
157
+ - 测试文件可改 → 安装时快照 `test/` 并在评测前恢复。
158
+ - venv 可伪造 → venv 校验。
159
+
160
+ ### 3.6 FeatureBench
161
+ - 同 SWE:RESTORE tests/、venv 校验、skipped 不算通过、resolved 需 F2P 通过。
162
+
163
+ ### 3.7 Neural-CPP
164
+ - 隐藏测试在 build 后读取 → 改为启动即快照到内存。
165
+ - nn.hpp 可改 → 不强制(公开接口语义不得改但无校验);评测用候选头文件,保留为已知限制并提示人工审计。
166
+ - score/resolved 文档未定义 → README/TASK 补充。
167
+ - speedGeomean 混 dtype/绝对 GFLOPS → README 明确口径。
168
+
169
+ ### 3.8 Neural-FP32
170
+ - 无总超时 → 增加 30 分钟总 deadline,单次调用 60s(与 pendulum oracle 对齐)。
171
+ - build/候选进程继承 EVAL_* → 剥离。
172
+ - 覆盖范围小于 TASK 文字(广播/conv groups/stride 等未测)→ TASK.md 澄清“本 CLI 评测固定形状;广播等能力需自行保证”,避免“承诺=评测”的误解。
173
+ - 速度包含进程启动 → README 明确这是“含启动开销的端到端吞吐”。
174
+
175
+ ### 3.9 Neural-CIFAR
176
+ - hidden labels 与 images 同目录 → 标签只读入内存、images 复制到独立临时目录。
177
+ - hidden 缺失时评测内联网下载 → 保留 fallback(README 已写 fetch 脚本),错误信息更明确。
178
+ - FPS 含模型加载 → README 明示口径。
179
+ - 不检查 build/train → README 标注仅 infer/nn_task 被评测。
180
+
181
+ ### 3.10 Neural-Pendulum
182
+ - autoBind/run 链路失效 → 随 1.1 修复;eval_submit/eval_test 可用。
183
+ - meta.started_at 被每次 eval 覆盖 → 只在缺失时写,用 run.createdAt。
184
+ - final_score 被丢弃 → hostTest 把 final_score 写入事件与 done 文件。
185
+ - control/sim stderr 死锁 → stderr=DEVNULL;selector 改为自定义 LineReader(二进制 + 内部缓冲)。
186
+ - t_can 容差 < vs <= → 改 <=;不影响 ≥10 判定。
187
+ - 构建环境剥离 EVAL_*。
188
+
189
+ ---
190
+
191
+ ## 4. 其它(已修/记录)
192
+
193
+ - reveal 路由:spawn 错误未处理 → 等 spawn 成功再返回,失败返回 500;路径检查用 realpath。
194
+ - JobManager 重启后不杀旧进程 → 记录 pid,启动时对 interrupted job 尝试杀进程组。
195
+ - Job 日志/结果路径校验、detail 读取范围不变。
196
+ - `install()` / `prepare` / `runSetup` 死代码 → 删除;测试改为使用 startInstall/新 API。
197
+ - 包 `exports.types` 指向未生成 d.ts → 移除 types 字段;构建脚本补 native。
198
+ - prompt 硬编码分钟数 → 按当前配置插值。
199
+ - 文档/文案/包装器 docstring 复制粘贴 → 修正。
200
+ - `forbiddenPaths` 通配符被静默丢弃 → 截断到首个通配符作为前缀规则并在设置页说明。
201
+ - `cleanupCifarLock` 硬编码 ~/.dsh 与 dshHome 不一致 → 统一为 dshHome()(CIFAR 缓存仍按 README 固定在 ~/.dsh,README 与代码一致化:缓存路径以 dshHome 为准)。
202
+ - CIFAR tar 解压无 filter → 加 `filter='data'`(Python 3.12+ 兼容处理)。
203
+ - prices 文件死链 → 每任务文件名 + 容错。
204
+
205
+ ---
206
+
207
+ ## 5. 修复后仍需注意(残留风险)
208
+
209
+ 1. **评测隔离**:eval 进程与候选代码同用户同机,属结构性风险;生产跑分请使用独立账号/容器。
210
+ 2. **隐藏数据**:host `~/.dsh/eval-guard` 与插件目录对同用户可读;审计恢复后正常 agent 工具无法读,但宿主进程/被评测二进制仍可读。
211
+ 3. **deadline 不持久化**:DSH 重启/HMR 会丢 deadline。
212
+ 4. **任务覆盖**:单结果评测是“自查”定位,quick 档覆盖面小,不能代替正式排行。
213
+ 5. **neural-cpp 公开头文件**:未做哈希校验,需赛后人工审计。
214
+ 6. **neural-cifar/torch 环境**:评测机需安装 torch/numpy,README 依赖清单已注明。
215
+ ---
216
+
217
+ ## 6. 本轮修复的验证记录
218
+
219
+ 在 2026-10-22 的修复后执行:
220
+
221
+ - 宿主半 `tsc --noEmit`(以 DSH 0.2.1-alpha.1 的 built d.ts 映射 cordis/schemastery):通过。
222
+ - `tsdown` 构建 host + client bundle:通过。
223
+ - `node scripts/build-native.mjs` 重建 supervisor:通过(沿用既有 -Wall 告警)。
224
+ - `node test/simulate.ts`:通过(真实 header 形状、isMain/子代理、路径审计、黑名单 goal/drawio、autoBind cwd、deadline 宽限、descendants 清理、owned job 过滤、enable/disable、confine argv 含 --cwd)。
225
+ - `node test/wrap.ts`、`test/matrix.ts`、`test/runtime.ts`、`test/python-runtime.ts`、`test/ptc.ts`、`test/entry.ts`、`test/client-entry.ts`:通过(bwrap 允许/拒绝、网络拒绝、node/gcc/python/PTC 导入、入口冒烟)。
226
+ - 修改过的 Python 评测脚本全部通过 `python3 -m py_compile`;四个 neural 任务 asset zip 重新打包并通过 `unzip -t`。
227
+ - 未执行:commit0/SWE/FeatureBench 的完整端到端评测(需要 clone + venv + 网络,成本高);neural 任务完整评测(需要数十分钟 CMake/torch 运行)。这些路径的改动已按“先快照/先校验、再构建/再评测”的顺序静态核对。
228
+
229
+ ### 仍未端到端验证的点
230
+
231
+ 1. workspace 位于 host /tmp 时的 bwrap 顺序修复(本会话的工具沙箱无法访问 host /tmp)。
232
+ 2. 评测 job 的真实 run(需要设置页点击安装/评测,或在宿主侧启动完整 DSH)。
233
+ 3. CIFAR hidden 数据下载与 infer 端到端(需要网络与训练好的模型)。
234
+ 4. neural-pendulum 的 eval_submit/eval_test 完整闭环(需要真实会话运行;autoBind 依赖 header.cwd 现在已修正)。
235
+
package/README.md CHANGED
@@ -2,9 +2,12 @@
2
2
 
3
3
  在 DSH 中启用后,约束**所有用户主对话**:
4
4
 
5
- - 只能读写会话工作区;工作区外(包括 /tmp)不可访问。
6
- - 禁止联网、子代理、Agent Team/跨 agent 通信、读取其它工作区。
7
- - 工具黑名单可配置;未知工具默认放行,但 DSH 内置与 dsh-ops 的工具会做参数路径审计。
5
+ - 文件类工具(read/write/edit/grep/glob/ops_*/drawio_* 等)做参数路径审计:只允许修改会话工作区;工作区之外允许读取“用户不可写但可读”的文件(系统文件、只读资料),用户可写的数据目录仍不可读写。进程沙箱内 `/tmp` 映射到工作区 `.tmp`;文件工具不会重写路径,读写 `/tmp` 请直接使用工作区内的 `.tmp` 路径。
6
+ - 进程类工具(bash / run_code / 后台任务)由 bwrap + seccomp supervisor 二次约束:只读系统视图、工作区可写、私有 /tmp、无网络;进入沙箱前清空继承环境,只回填 PATH/HOME/TMPDIR/XDG/LANG 等非敏感变量,避免宿主 API key / 代理泄漏;越界访问会记录并终止进程组。
7
+ - 禁止联网、子代理、Agent Team/跨 agent 通信,以及可绕过单次评测的持久化工具(goal / schedule / drawio / canvas 等)。用户 fork 出的会话仍按主会话约束;子代理会话本身也同样受工具审计和进程沙箱约束(黑名单只是额外的一层)。
8
+ - 工具黑名单可配置;未知工具默认放行。DSH 内置与 dsh-ops 的文件工具会做参数路径审计。
9
+
10
+ > 完整性修复记录、仍存风险与逐任务覆盖范围见 [ISSUES.md](./ISSUES.md)。
8
11
 
9
12
  ## 时间限制
10
13
 
@@ -13,10 +16,11 @@
13
16
  - 关闭限时后再次给已有 deadline 的会话发送消息,会清空该会话自己的 deadline;其它会话不受影响。
14
17
  - 重新打开限时后,已有会话不会自动恢复 deadline;下一次用户消息才会重新计时。
15
18
  - 每个会话独立计时;可以同时运行多个不同时长、有的开启限时有的不开启的会话。
16
- - deadline 到点只终止对应会话及其子代理/后台任务,不影响其它会话。
19
+ - deadline 到点终止对应会话及其**子代理会话**与**该会话拥有的后台任务**;不影响其它会话。turn 结束后有 5 秒空闲宽限,避免与后台任务的注册竞争。子代理按 `origin/delegationDepth` 识别;用户 fork 会话的 `parentSession` 是 seed 血缘,不会被当作子代理误杀。
17
20
  - 关闭「评测守护」总开关会清空全部 deadline 并停止约束;总开关与单轮限时开关是两套状态。
21
+ - 已知边界:deadline 仅保存在内存,DSH 重启/HMR 重载会丢失;重启后下一条用户消息重新计时。
18
22
 
19
- 设置页选择任务时会自动把「最长时长 + 限时开关」写成该任务默认值并立即显示,用户可以随后手动修改:
23
+ 设置页选择任务时会自动把「最长时长 + 限时开关」写成该任务默认值并立即显示,用户可以随后手动修改;提示词中的分钟数会随当前配置一起变化:
20
24
 
21
25
  | 任务类型 | 默认限时 |
22
26
  |---|---|
@@ -27,14 +31,15 @@
27
31
  | Neural-CPP 纯 C++ 张量后端 | 1440 分钟,默认关闭 |
28
32
  | Neural-FP32 纯 C++ 运算与性能 | 1440 分钟,默认关闭 |
29
33
  | Neural-CIFAR 从零训练图像分类 | 1440 分钟,默认关闭 |
34
+ | Neural-Pendulum 从零训练三节摆控制器 | 1440 分钟,默认关闭 |
30
35
 
31
36
  ## 任务与安装
32
37
 
33
- 设置页可安装十一个任务包:
38
+ 设置页可安装十二个任务包:
34
39
 
35
40
  - 原 5 个比赛任务:坦克大战、仓储调度、圈地、炸弹人、夺旗。
36
41
  - 3 个长时单任务:Commit0 单库实现、SWE-Bench Pro 单任务、FeatureBench 单 feature。
37
- - 3 个纯 C++ 项目:Neural-CPP 张量后端、Neural-FP32 运算与性能、Neural-CIFAR 图像分类训练。
42
+ - 4 个纯 C++ 项目:Neural-CPP 张量后端、Neural-FP32 运算与性能、Neural-CIFAR 图像分类训练、Neural-Pendulum 三节摆控制器。
38
43
 
39
44
  Neural-CPP 安装时自动把 workspace.zip 解压到工作区根目录,并在完成后移除 setup.sh;agent 从根目录的 CMakeLists.txt 开始。工作区只包含 TASK.md、CMakeLists.txt 和 include/nn/nn.hpp;实现在 src/ 中从零完成,纯 C++17,无 Python/OpenCL/第三方库。
40
45
 
@@ -42,18 +47,28 @@ Neural-CPP 安装时自动把 workspace.zip 解压到工作区根目录,并在
42
47
 
43
48
  Neural-FP32 是独立的新任务:固定 fp32,不做完整训练;agent 从零实现 `build/nn_task` CLI,覆盖逐元素、matmul、linear、relu、softmax、layernorm、mse、conv2d、对应反向传播、AdamW 和 SGD momentum。评测侧用 PyTorch 在相同数据和参数上计算参考值,逐操作输出可执行性、是否通过误差阈值、加权平均相对误差、速度,并在最前面给出是否所有操作可执行、最大加权平均相对误差和速度几何平均;不提供统一 score,速度不受误差门控影响。
44
49
 
50
+ **评测覆盖**:CLI 评测使用固定形状(逐元素同形状 64×256、matmul 256³、conv2d 单组 stride1/pad1/dil1/groups1 等),不会覆盖广播、groups/stride/dilation/非方形核的所有组合;单次 CLI 调用 60 秒、整轮 30 分钟。速度是“含进程启动与文件 IO 的端到端吞吐”,不是纯 kernel 性能。
51
+
45
52
  Neural-CIFAR 在 Neural-FP32 的基础上要求 agent 用同一套 C++ 训练框架构造并训练 CIFAR-10 图像分类网络。任务不限时,agent 定位为神经网络全栈设计与优化大师,提交前应尽可能优化;速度和未知验证集准确率都是重要指标,会参与世界顶尖水平比拼。安装时下载并准备 50k train split;隐藏 10k test split 由独立评测目录 `dsh-eval-guard/neural-cifar-eval/fetch_cifar.py` 获取并放在该目录的 `hidden/`,不作为工作区文件。评测保留全部原算子指标,并额外用 4 线程和全部逻辑 CPU 分别跑推理,输出验证准确率、FPS、平均单图耗时;4 线程 0.02s/image 只报告,不门控。
46
53
 
47
- CIFAR-10 下载缓存固定在用户 home 下:`~/.dsh/eval-guard/cache/cifar10/`,保存 train/val 的 images/labels。下载使用 `~/.dsh/eval-guard/cache/cifar10/.download.lock` 独占锁,并实时打印进度;锁存在时认为其他 DSH 实例正在下载,任务安装/评测会提示等待或手动删除锁文件。缓存完整且无锁时直接复用。设置页新增「CIFAR download mirror」和「CIFAR download proxy」输入框:mirror 可选 Toronto 官方、Toronto Cave 或自定义 tar.gz URL,proxy 只用于 CIFAR 下载。按任务安装和评测时分别传给 setup/fetch 脚本。
54
+ **评测口径**:评测只检查 `build/nn_task` 与 `build/infer`(不跑 `build/train`);FPS/单图耗时包含进程启动与模型加载;验证标签只读入评测进程内存,候选 `infer` 拿到的是独立临时目录中的图像副本,看不到标签。
55
+
56
+ CIFAR-10 下载缓存固定在 DSH home 下(默认 `~/.dsh/eval-guard/cache/cifar10/`),保存 train/val 的 images/labels。下载使用 `.download.lock` 独占锁,并实时打印进度;锁存在时认为其他 DSH 实例正在下载,任务安装/评测会提示等待或手动删除锁文件。缓存完整且无锁时直接复用。设置页新增「CIFAR download mirror」和「CIFAR download proxy」输入框:mirror 可选 Toronto 官方、Toronto Cave 或自定义 tar.gz URL,proxy 只用于 CIFAR 下载。按任务安装和评测时分别传给 setup/fetch 脚本。
48
57
 
49
58
  所有任务的后台安装被取消或失败时,会删除本次安装已搬入工作区的文件,并清空工作区。清理只会在安装开始前工作区确实为空时执行,原工作区有内容时绝不触发。Neural-CIFAR 还会删除本次安装拥有的 CIFAR 下载锁,但不会删除其他 DSH 实例的锁。
50
59
 
51
- 评测时在临时目录独立构建,然后从 assets/neural-cpp/hidden/ 注入 C++ 测试源码;测试数据由固定种子在进程内生成,不依赖或复制外部数据文件。
60
+ Neural-Pendulum 要求从零实现纯 C++17、仅 CPU、fp32 的神经网络基础设施,并用它训练控制器驱动预编译三节摆从接近全向下起摆、保持全向上 10 秒。后端评测与 Neural-FP32/Neural-CIFAR 使用同一套算子/阈值(单次调用 60 秒)。算子评测全部通过后才驱动 build/control,在固定初始状态上统计连续全向上时间 t_can。评测脚本在独立目录 `dsh-eval-guard/neural-pendulum-eval/`;宿主侧提交与测试工具为 eval_submit / eval_test,工具的注册依赖会话级 run 绑定。
61
+
62
+ **分数**:eval_test 返回 stage / t_can / completed / error;时间积分 `final_score` 写入宿主侧事件与完成标记(`~/.dsh/eval-guard/neural-pendulum/<workspace>/done`),用于赛后排行,不返回给 agent。分数在**测试请求时刻**切换,当前测试结果也计入本次积分;宿主按事件重新计算最终值,而不是使用“评测完成时刻”的旧值。起算时间取首次提交写入的 meta.json。
52
63
 
53
- 结果返回 coreAccuracy(核心 C++ 测试通过率)、matrixAccuracy、逐类型 metrics(f32/int128/MXFP4 的矩阵与反向准确率、平均绝对误差、fwd/bwd 毫秒、fwd/bwd GFLOP/s)、speedGflops,以及按矩阵吞吐计算的 speedGeomeanGflops 和 matrixSizes(f32/i128/MXFP4 均为 256×256×256)。确定性项目使用 4 组独立输入取平均;MXFP4 RNE 和随机舍入分开统计,随机舍入使用 2 组输入×每组 1024 次采样,逐元素比较参考均值/标准差和候选均值/标准差,按 3σ 和 0.1–10× 标准差规则统计正确率。参考值由测试侧独立标量实现先算完,再调用候选实现,参考计算不计入候选耗时。隐藏测试不在工作区,agent 无法读取。开发要求线程数最多 4,评测阶段使用全部逻辑 CPU。
64
+ 评测时在临时目录独立构建,然后从 assets/neural-cpp/hidden/ 注入 C++ 测试源码;隐藏测试在候选构建**开始前**读入内存,构建完成后再落盘编译,测试数据由固定种子在进程内生成,不依赖或复制外部数据文件。
65
+
66
+ 结果返回 coreAccuracy(核心 C++ 测试通过率)、matrixAccuracy、逐类型 metrics(f32/int128/MXFP4 的矩阵与反向准确率、平均绝对误差、fwd/bwd 毫秒、fwd/bwd GFLOP/s)、speedGflops,以及按矩阵吞吐计算的 speedGeomeanGflops 和 matrixSizes(f32/i128/MXFP4 均为 256×256×256)。确定性项目使用 4 组独立输入取平均;MXFP4 RNE 和随机舍入分开统计,随机舍入使用 2 组输入×每组 1024 次采样,逐元素比较参考均值/标准差和候选均值/标准差,按 3σ 和 0.1–10× 标准差规则统计正确率。参考值由测试侧独立标量实现先算完,再调用候选实现,参考计算不计入候选耗时。隐藏测试不在工作区,agent 无法读取。
54
67
 
55
68
  原 5 个任务直接放入打包好的 workspace.zip。后 3 个任务在安装时由 host 侧 setup 脚本按固定 commit clone 仓库、创建 .venv 并安装依赖;安装完成后会清理 `.git`、`setup.sh`、`remove.patch`、`spec.pdf.bz2` 等安装产物,工作区只保留任务本身素材。Commit0 的 `pytest.ini` 会去掉 coverage 参数,保证默认测试命令在沙箱内可运行。agent 运行时仍然禁网,使用工作区内的 .venv 跑测试;agent 可以自行 `git init` 或写自己的脚本。
56
69
 
70
+ **测试完整性**:安装成功时会把 commit0 的 `tests/ + pytest.ini`、SWE-Bench Pro 的 `test/`、FeatureBench 的 `tests/ + conftest.py` 快照到宿主侧(`~/.dsh/eval-guard/task-baseline/<workspace>/`),评测前覆盖回候选副本并删除候选新增的 conftest.py;同时记录 .venv 关键文件(python 指向、pyvenv.cfg、.pth、pytest 包)指纹,指纹不符直接判评测失败。因此“改测试 / 换 python / 改 pytest 包”不再能伪造通过。
71
+
57
72
  安装是后台任务:
58
73
 
59
74
  - 可分别选择 clone 远端、pip 镜像、Git 代理和 pip 代理。
@@ -86,16 +101,17 @@ Gitee/GitCode 都使用 git fetch --depth 1 origin <任务 commit> 验证。GitL
86
101
 
87
102
  设置页安装/评测共用一组任务和工作区选择;「评测当前工作区」只评测一个结果,不生成排行。
88
103
 
89
- 插件 eval/ 目录内置全部 11 个任务的单结果评测脚本:
104
+ 插件 eval/ 目录内置全部 12 个任务的单结果评测脚本:
90
105
 
91
- - Commit0:单元测试通过率。
92
- - SWE-Bench Pro / FeatureBench:隐藏 F2P/P2P 测试;全部通过才 resolved,同时返回 passRate。
93
- - Neural-CPP:独立编译隐藏 C++ 测试,返回 accuracy 与 matmul speedGflops;数据在测试进程内按固定种子生成。
106
+ - Commit0:单元测试通过率(测试来自安装时快照,评测前恢复)。
107
+ - SWE-Bench Pro / FeatureBench:隐藏 F2P/P2P 测试;显式要求 F2P 节点全部通过且 P2P 全部通过才 resolved,skipped 不算通过。
108
+ - Neural-CPP:独立编译隐藏 C++ 测试(启动即快照,构建后编译),返回 accuracy、matrixAccuracy、speedGeomean 与 score/resolved。
94
109
  - Neural-FP32:调用候选 build/nn_task,用 PyTorch 参考值统计每个操作的 MRE 和速度;汇总项在最前面,不输出统一 score。
95
110
  - Neural-CIFAR:保留 Neural-FP32 的算子评测,加载训练好的模型,在隐藏验证集上分别用 4 线程和全部线程测准确率/FPS;独立脚本在 `dsh-eval-guard/neural-cifar-eval/`。
96
- - Tank / Warehouse / Land / Bomberman / CTF:运行官方引擎/裁判,只返回当前工作区候选者结果,不生成排名。
111
+ - Neural-Pendulum:先运行与 Neural-FP32/Neural-CIFAR 相同的 PyTorch 参考算子评测(全部通过才继续),再构建并驱动 build/control,用宿主事件时间积分计分;独立脚本在 `dsh-eval-guard/neural-pendulum-eval/`。
112
+ - Tank / Warehouse / Land / Bomberman / CTF:运行官方引擎/裁判,只返回当前工作区候选者结果,不生成排名;使用 quick 档(tank 20 局仅 baseline、warehouse 仅 pub_small、land 仅单挑、bomberman 仅 2 人、ctf 仅 2/3 方),不能代替正式排行。
97
113
 
98
- 评测也是后台任务,日志和结果实时显示,持久化在 jobs 目录。
114
+ 评测也是后台任务,日志和结果实时显示,持久化在 jobs 目录。评测进程继承的环境变量已收敛为一份白名单,`EVAL_*` 句柄不会再传给候选子进程。
99
115
 
100
116
  ## 任务来源
101
117
 
@@ -127,6 +143,8 @@ Gitee/GitCode 都使用 git fetch --depth 1 origin <任务 commit> 验证。GitL
127
143
 
128
144
  仓储调度任务包同样只放 workspace.zip;包内 TASK.md 已改写成单人单次 90 分钟版本,保留了原 baseline/、src/、workloads/ 和 tools/。
129
145
 
146
+ 评测用的 arena kit 位于 `eval/arena/<task>/workspace`,与 agent 工作区不是同一份快照(kit 保留源码形式的 baseline、历史 bot 与不同的 README/clock.py),只用于提供基准与裁决程序;单结果评测不启用历史对手。
147
+
130
148
  ## 构建
131
149
 
132
150
  ~~~bash
@@ -150,10 +168,20 @@ DSH_CHECKOUT=/path/to/deepseek-harness scripts/install.sh web
150
168
  - gcc(构建 native supervisor 时)
151
169
  - unzip(安装任务素材时)
152
170
  - Python 3(长任务 setup 与评测)
171
+ - PyTorch + numpy(neural 任务的算子和模型评测;缺少时 neural-fp32/cifar/pendulum 会报明确错误)
153
172
 
154
173
  ## 已知边界
155
174
 
156
- - 只支持 Linux。
175
+ - 只支持 Linux;启用守护前会探测 bwrap 与 unprivileged user namespace,探测失败时设置页显示原因且不生效。
157
176
  - seccomp 用户通知的路径检查与 open 之间存在极小的 TOCTOU 窗口;bwrap 只读/无网络挂载是第二层内核边界。
158
- - 进程审计只覆盖被拦截的文件/网络 syscall;正常 syscall 不记录。
177
+ - io_uring 被拒绝(以 EPERM 软拒绝,不杀进程);正常 syscall 不记录,进程审计只覆盖被拦截的文件/网络 syscall。
178
+ - 工具路径审计只覆盖已知文件工具(DSH 内置、dsh-ops、drawio);未知工具默认放行,这是产品选择,不是完整内核边界。
179
+ - `forbiddenPaths` 的 `!` 例外只放宽审计;它不会把宿主 home、DSH 状态目录、共享 /tmp 或 workspace 的祖先 ro-bind 进沙箱。系统目录本身已只读可见,通常不需要 `!`。
180
+ - 只读文件放行是产品选择:工作区之外“用户不可写但可读”的文件允许读取,因此只读安装的隐藏资产/数据不在 OS 权限层面被隐藏;真正需要隔离的隐藏数据仍需独立用户/容器。
181
+ - 进程沙箱会清空继承环境,但 PATH/HOME/TMPDIR/XDG/LANG/TZ/USER 等非敏感变量按白名单回填;run_code 的 PTC 控制通道标记和打包 PTC 的 NODE_OPTIONS 由 supervisor 从自身环境恢复。
182
+ - native supervisor 的架构门在源码层支持 x86_64/aarch64;仓库内的预编译二进制只对应构建它的架构,其它架构必须在本机运行 `npm run build:native`。
183
+ - 文件工具的路径审计是“先检查后打开”,与进程沙箱的 seccomp TOCTOU 一样存在极小的 symlink 竞态窗口;不要把它当作文件系统的完整边界。
184
+ - 评测进程与候选代码仍以同一个 OS 用户运行:安装了恶意 CMakeLists/候选二进制后,理论上仍可读取同用户文件并篡改评测器。生产跑分建议用独立账号或容器执行 eval job;本插件已做的缓解是:环境变量白名单、隐藏数据先读入内存、候选子进程剥掉 EVAL_*、测试基线恢复、venv 指纹校验。
185
+ - commit0 没有官方隐藏测试:评分基于“安装时快照恢复的仓库原始测试”;这意味着原始测试本身仍是评分依据。
186
+ - 单结果评测是自查工具:quick 档覆盖面小,不能代替正式赛排行;正式负载/隐藏负载需在评测侧另行准备。
159
187
  - 设置页使用内联样式,不依赖额外 CSS 构建链。
Binary file
Binary file
Binary file
@@ -1,8 +1,12 @@
1
- # Neural-Pendulum 任务规格 v1.3
1
+ # Neural-Pendulum 任务规格 v1.4
2
2
 
3
3
  本文件是已确定的任务内部规格。实现、评测器、workspace 素材以此为准。
4
4
  后续除非明确修改规格,否则不再重新讨论这些规则。
5
5
 
6
+ v1.4 变更:后端基础设施评测与 Neural-FP32 / Neural-CIFAR 统一为“固定 CLI +
7
+ PyTorch 参考值 + 加权平均相对误差阈值”,不再使用 include/nn/nn.hpp 头文件契约和
8
+ 隐藏 C++ 基础设施测试。
9
+
6
10
  ## 1. 任务标识
7
11
 
8
12
  - task id: neural-pendulum
@@ -15,11 +19,11 @@
15
19
 
16
20
  agent 必须:
17
21
 
18
- 1. 从零实现一套神经网络基础设施(张量、算子、反向传播、优化器、模型序列化、线程池)。
22
+ 1. 从零实现一套神经网络基础设施(张量、算子、反向传播、优化器、线程池;控制器权重的打包方式自定,评测不要求特定序列化格式)。
19
23
  2. 使用该基础设施训练一个神经网络控制器。
20
24
  3. 控制预编译双驱动三节摆:第一、第三关节施加有限力矩,中间关节被动,从全向下起摆,并保持三根杆全部向上至少 t_tgt = 10.0 s。
21
- 4. 保证基础设施实现 `include/nn/nn.hpp` 契约并通过隐藏测试。
22
- 5. 提交的源码中不得出现 torch,测试环境不提供 Python/torch。
25
+ 4. 保证基础设施通过 `build/nn_task` 固定 CLI 的数值评测:评测侧用 PyTorch 在相同数据上计算参考值,逐操作比较加权平均相对误差并对照阈值。
26
+ 5. 提交的源码中不得出现 torch;候选运行时不提供 Python/torch。
23
27
 
24
28
  允许在开发阶段使用 PyTorch 做数值自查和参考,但提交源码必须完全独立。
25
29
 
@@ -179,39 +183,43 @@ cmake --build build -j4
179
183
  必须产生:
180
184
 
181
185
  ~~~
182
- build/libnn.a
186
+ build/nn_task
183
187
  build/control
184
188
  ~~~
185
189
 
186
- ### 8.1 基础设施测试入口
190
+ ### 8.1 基础设施数值评测入口
187
191
 
188
- 基础设施实现位于 `src/nn/*.cpp`,由 CMake 构建静态库 `build/libnn.a`;公开头文件 `include/nn/nn.hpp` 为不可修改的 API 契约。
192
+ 神经网络基础设施通过 `build/nn_task` 固定 CLI 暴露(协议见 TASK.md)。评测侧在独立评测进程中:
189
193
 
190
- 评测侧独立编译隐藏测试并链接 `build/libnn.a`。
194
+ 1. 用固定种子生成输入与参数
195
+ 2. 用 PyTorch 在相同数据上计算参考输出
196
+ 3. 调用候选 `build/nn_task` 子命令,读取其写出的 float32 结果
197
+ 4. 逐操作计算加权平均相对误差
191
198
 
192
- 隐藏测试覆盖:
199
+ ~~~
200
+ mre = sum(|candidate - reference|) / sum(|reference|)
201
+ ~~~
193
202
 
194
- - fp32 tensor、形状与广播
195
- - elementwise add/sub/mul/div
196
- - matmul / linear
197
- - relu / softmax
198
- - layernorm
199
- - conv2d(stride/padding/dilation/groups)
200
- - MSE
201
- - matmul/linear/relu/layernorm/conv2d/MSE 反向
202
- - SGD momentum
203
- - AdamW
204
- - 模型保存/加载
205
- - 线程池
203
+ 覆盖操作与阈值:
206
204
 
207
- 任一测试失败:
205
+ | 操作 | 阈值 |
206
+ | --- | --- |
207
+ | elementwise add/sub/mul/div、relu、mse、sgd-momentum | 1e-6 |
208
+ | matmul、linear、softmax、layernorm、adamw | 1e-5 |
209
+ | conv2d、matmul/linear/relu/layernorm/mse/conv2d backward | 1e-4 |
210
+
211
+ 每个操作使用 3 组独立数据。以下任一情况:
208
212
 
209
213
  ~~~
210
214
  stage = infra
211
215
  score = -1
212
216
  ~~~
213
217
 
214
- 占位符返回空结果按错误处理。
218
+ - 子命令不可执行、崩溃或超时(单次调用 60 秒)
219
+ - 输出文件缺失或元素数不符
220
+ - 加权平均相对误差超过阈值
221
+
222
+ 速度(GFLOP/s)同时统计并报告,但不参与通过判定。参考数据、阈值和评测过程均不在工作区中。
215
223
 
216
224
  ### 8.2 控制器入口
217
225
 
@@ -266,7 +274,7 @@ capped_t_can = min(t_can, t_tgt)
266
274
  完成条件:
267
275
 
268
276
  ~~~
269
- infra_ok == true
277
+ infra_ok == true(全部算子可执行且误差不超阈值)
270
278
  且 t_can >= t_tgt
271
279
  ~~~
272
280
 
@@ -302,8 +310,8 @@ infra_ok == true
302
310
 
303
311
  ~~~
304
312
  no_submission 没有提交快照
305
- compile CMake 构建 libnn.a / control 失败
306
- infra 隐藏基础设施测试编译、链接或运行失败
313
+ compile CMake 构建失败,或未产出 build/nn_task / build/control
314
+ infra build/nn_task 算子数值评测失败(不可执行/崩溃/超时/输出缺失/误差超阈值)
307
315
  controller 控制器启动/协议/崩溃/超时/非法输出
308
316
  simulation 仿真异常/NaN/仿真超时
309
317
  scoring 正常测试但 t_can < t_tgt
@@ -400,7 +408,7 @@ infra_ok = true
400
408
  - 无提交
401
409
  - 源码缺失
402
410
  - 编译失败/超时
403
- - 基础设施测试失败
411
+ - 算子数值评测失败
404
412
  - 控制器加载/接口/崩溃/超时/非法输出
405
413
  - 仿真 NaN/异常/超时
406
414
  - 测试请求本身失败
@@ -439,11 +447,10 @@ cmake --build build -j4
439
447
 
440
448
  规则:
441
449
 
442
- - 仅允许 C++17 + CMake + C++ 标准库
443
- - 无网络
444
- - 无 torch
445
- - 无 Python 运行时
446
- - 源码中出现 torch/Python 依赖:测试失败或赛后人工审核无效
450
+ - 候选仅允许 C++17 + CMake + C++ 标准库
451
+ - 候选无网络;评测侧不向候选提供 Python/torch
452
+ - 候选源码中出现 torch/Python 依赖:算子评测失败或赛后人工审核无效
453
+ - 评测侧使用 PyTorch(CPU、确定性、单线程)计算数值参考值
447
454
  - 编译失败:stage = compile,score = -1
448
455
 
449
456
  ## 16. 赛后人工审核