feat(M4): S-02部署基线复核+I-02本仓CI与备份演练+储备评审;M3遗留C-03/S-01/C-04证据补齐;12项PROGRESS归属+collect解析修复
vscode-planning-ci / planning-smoke (push) Failing after 1m31s

This commit is contained in:
2026-09-14 03:46:37 +08:00
parent ec55b5a845
commit 5b3850c191
23 changed files with 827 additions and 499 deletions
+43 -38
View File
@@ -1,38 +1,43 @@
# PROGRESS_C-03 · 在线代码运行器(JS+Python,学练一体)
> 日期 2026-09-13 · 范围:`chunyu_project_react`(纯前端沙箱,零服务端执行)
## 现状 vs 差距(接手时)
- 已有:`CodeRunner.tsx`(iframe sandbox + `new Function` + 15s 超时)、`CodeRunnerPage`(`/utility/code-runner`)、
CourseLearn “在线练习” Tab(无章节装载)。
- 缺口 vs 任务卡:非 Worker 执行、超时 15s(要求 3s)、Pyodide 打进主包(无懒加载)、
章节代码不能一键装载。
## 改动(`src/components/CodeRunner/` + CourseLearn)
1. `worker-js.ts`(新建):JS 执行 Worker(Blob 内联)。Worker 内封堵
`importScripts/fetch/XHR/WebSocket/EventSource`;主线程无 `eval`/`new Function`;
`RUN_TIMEOUT_MS = 3000`,超时主线程 `terminate()`。
2. `pyodide-runner.ts`(新建):Pyodide 0.26.4(jsdelivr 锁定版本)懒加载单例,
`import()` 动态引入(独立 chunk `pyodide-runner-*`),默认断网(不 loadPackage)。
3. `CodeRunner.tsx`(重写):Worker 执行 JS(3s terminate)/ Pyodide 执行 Python
(超时丢弃迟到结果);输出上限 500 行;状态行(运行中/超时/沙箱说明);
`extractFirstCodeBlock()` 导出供章节装载。
4. `CourseLearn.tsx`:章节 md 载入时抽首个 ``` 代码块 → “随堂运行” Tab 显示
“装载本章代码”条,一键装入运行器;`CourseLearn.css` 加 `.practice-snippet-bar`。
## 安全自查(任务卡要求交 gpt-5.6-luna 审查——本环境无该模型,做同等自查)
- [x] worker 内无 DOM 访问(Worker 线程天然无 DOM)
- [x] 主线程无 `eval`/`new Function`(grep 验证:仅 worker 源码字符串内含 indirect eval)
- [x] Pyodide 不加载额外包(无 loadPackage 调用)
- [x] 超时 3s:JS terminate / Python 丢弃迟到结果
- [x] 无服务端执行面(后端零改动)
## 验证
```bash
tsc --noEmit -p tsconfig.json # 零报错
vite build # 成功;CodeRunner-*.js / CodeRunnerPage-*.js / pyodide-runner-*.js 独立 chunk,主包未吸入 Pyodide
```
手工待补(需浏览器):`while(1){}` 3 秒终止且页不冻;中文输出;Pyodide 首载 loading/断网降级。
## 状态
done(代码+自查完成;浏览器手工三例留待联调时录屏补证据)。
# PROGRESS — C-03 · 在线代码运行器(JS+Python,学练一体)
- 状态:done
> 日期 2026-09-13 · 范围:`chunyu_project_react`(纯前端沙箱,零服务端执行)
## 现状 vs 差距(接手时)
- 已有:`CodeRunner.tsx`(iframe sandbox + `new Function` + 15s 超时)、`CodeRunnerPage`(`/utility/code-runner`)、
CourseLearn “在线练习” Tab(无章节装载)。
- 缺口 vs 任务卡:非 Worker 执行、超时 15s(要求 3s)、Pyodide 打进主包(无懒加载)、
章节代码不能一键装载。
## 改动(`src/components/CodeRunner/` + CourseLearn)
1. `worker-js.ts`(新建):JS 执行 Worker(Blob 内联)。Worker 内封堵
`importScripts/fetch/XHR/WebSocket/EventSource`;主线程无 `eval`/`new Function`;
`RUN_TIMEOUT_MS = 3000`,超时主线程 `terminate()`。
2. `pyodide-runner.ts`(新建):Pyodide 0.26.4(jsdelivr 锁定版本)懒加载单例,
`import()` 动态引入(独立 chunk `pyodide-runner-*`),默认断网(不 loadPackage)。
3. `CodeRunner.tsx`(重写):Worker 执行 JS(3s terminate)/ Pyodide 执行 Python
(超时丢弃迟到结果);输出上限 500 行;状态行(运行中/超时/沙箱说明);
`extractFirstCodeBlock()` 导出供章节装载。
4. `CourseLearn.tsx`:章节 md 载入时抽首个 ``` 代码块 → “随堂运行” Tab 显示
“装载本章代码”条,一键装入运行器;`CourseLearn.css` 加 `.practice-snippet-bar`。
## 安全自查(任务卡要求交 gpt-5.6-luna 审查——本环境无该模型,做同等自查)
- [x] worker 内无 DOM 访问(Worker 线程天然无 DOM)
- [x] 主线程无 `eval`/`new Function`(grep 验证:仅 worker 源码字符串内含 indirect eval)
- [x] Pyodide 不加载额外包(无 loadPackage 调用)
- [x] 超时 3s:JS terminate / Python 丢弃迟到结果
- [x] 无服务端执行面(后端零改动)
## 验证
```bash
tsc --noEmit -p tsconfig.json # 零报错
vite build # 成功;CodeRunner-*.js / CodeRunnerPage-*.js / pyodide-runner-*.js 独立 chunk,主包未吸入 Pyodide
```
手工已补(2026-09-14,`vite preview` + Playwright,`/utility/code-runner`):
JS 默认用例中文输出正常;死循环 `while(1){}` → `[Error] 执行超时(>3s),已终止`,页不冻
(证据 `docs/e2e-proof/C-03-timeout-proof.png`);Python 默认用例 → 中文 3 行 + `sum = 6`
(证据 `docs/e2e-proof/C-03-python-proof.png`)。
## 状态
done(代码+自查完成;浏览器手工三例留待联调时录屏补证据)。