33 KiB
33 KiB
Progress Log
Session: 2026-08-15
Phase 1:基线与第一批外围改造
- Status: complete
- Started: 2026-08-15
- Actions taken:
- 完成现有架构、课堂内核、大课编排和三端边界的并行只读审计。
- 与用户确认先封能力边界、后拆三端应用。
- 明确原互动课堂为受保护内核,外围恢复/增强功能。
- 验证
mcp__deepseek_harness__run已加载并能只读访问 OpenMAIC。 - 创建持久化计划、发现与进度记录。
- 尝试并行委派三项只读设计审计;底层调用未在超时后收束,已主动终止,未产生代码写入。
- 主线程核查 middleware、首页提交、generation-preview 会话恢复、课堂 learner 外挂和发布 Token 使用点。
- 确认前台生成 Session 的最小结构、文档 Blob 持久化要求及现有 E2E 与新双路径行为的差异。
- 实现首页双路径提交:普通需求继续走后台任务,材料/互动/职教模式写入前台 Session 后进入原
/generation-preview。 - 从 classroom learner 外层取消平行
AssistantPanel挂载,保留原 Stage 内 ChatArea/Roundtable。 - 用户要求停止使用 DeepSeek Harness;后续实现与验证全部切回主线程和本地工具。
- 更新首页 Playwright page object 和 4 条生成链路 E2E,使普通需求断言后台任务、互动模式断言原前台预览。
- 新增部署角色解析与
requireOpsAccess:生产默认 learner,ops 生产强制 ACCESS_CODE,会话校验在每个/api/courses/**路由重复执行。 - 首页与课堂发布入口改为由非敏感部署角色控制;浏览器不再读取或发送
NEXT_PUBLIC_COURSEWARE_PUBLISH_TOKEN。 - 课件发布 POST 在 ops 实例接受 ACCESS_CODE 会话,在独立 server 实例继续要求服务端 Bearer Token。
- Files created/modified:
task_plan.md(创建)findings.md(创建)progress.md(创建)lib/generation/foreground-session.ts(创建)tests/generation/foreground-session.test.ts(创建)app/page.tsx(修改:首页前台/后台双路径)app/classroom/[id]/page.tsx(修改:移除平行助教挂载)e2e/pages/home.page.ts(修改:动态前台/后台按钮与互动模式操作)e2e/tests/home-to-generation.spec.ts(修改:双路径断言)e2e/tests/full-happy-path.spec.ts(修改:显式互动模式)e2e/tests/slide-content-surface-647.spec.ts(修改:显式互动模式)e2e/tests/slide-scene-creation-gate.spec.ts(修改:显式互动模式)lib/config/deployment-role.ts(创建:部署能力契约)lib/server/ops-access.ts(创建:运营服务端守卫)tests/config/deployment-role.test.ts(创建)tests/server/ops-access.test.ts(创建)middleware.ts(修改:运营路由部署角色边界)app/api/courses/**/route.ts(修改:逐路由运营会话守卫)app/api/coursewares/route.ts(修改:ops 会话或 server token 双入口)lib/config/feature-flags.ts、lib/bundle/client-upload.ts、lib/bundle/use-publish-courseware.ts(修改:移除浏览器发布密钥)app/courses/[courseId]/page.tsx(修改:发布请求不再携带公开 token).env.example(修改:部署角色与服务端发布凭据说明)
Test Results
| Test | Input | Expected | Actual | Status |
|---|---|---|---|---|
| DeepSeek Harness 只读自检 | OpenMAIC package 基础信息 | 可读取且无写入 | 识别 openmaic@0.3.2,无文件变更 |
✓ |
| 前台 Session 单元测试 | tests/generation/foreground-session.test.ts |
标志映射、材料顺序与空材料会话正确 | 2 tests passed | ✓ |
| 首批 TypeScript 检查 | pnpm exec tsc --noEmit |
无类型错误 | exit 0 | ✓ |
| 首批针对性 ESLint | 首页、课堂外层、Session helper/test | 无 lint 错误 | exit 0 | ✓ |
| 首页双路径 Playwright | e2e/tests/home-to-generation.spec.ts |
后台 POST、互动模式前台路由、设置弹窗均正常 | 3 passed | ✓ |
| 部署角色与运营访问单测 | deployment role、ops access、bundle repo、course manifest | 角色/会话/旧发布合约均通过 | 4 files / 20 tests passed | ✓ |
| learner 部署边界 Playwright | 隐藏入口、拒绝 API、重定向运营页 | 三项全部成立 | 1 passed | ✓ |
| Phase 2 course-framework 单测 | 主契约校验、旧数据兼容、顺序互斥、runner 输入传递 | 全部通过 | 4 files / 31 tests passed | ✓ |
| Phase 2 TypeScript | pnpm exec tsc --noEmit |
无类型错误 | exit 0 | ✓ |
| Phase 2 定向 ESLint | course framework、运营审核 UI、生成路由和测试 | 无 lint 错误 | exit 0 | ✓ |
| Phase 3 连续性与互动回归 | course framework、Interactive prompt/backend、task-engine/media/scene 回归 | 全部通过 | 10 files / 70 tests passed | ✓ |
| Phase 3 TypeScript / ESLint | 全量 TSC 与 Phase 3 触及文件 | 无错误 | exit 0 | ✓ |
| 定向既有测试基线(此前审计) | tests/bundle tests/qa tests/course-framework tests/courseware |
全部通过 | 14 files / 83 tests passed | ✓ |
| i18n key check(此前审计) | node scripts/check-i18n-keys.mjs |
全部语言键完整 | 9 种语言各缺 158 个新键 | ✗ 已记录,非本批核心阻塞 |
Phase 2:大型课程主 Agent 契约
- Status: complete
- Started: 2026-08-15
- Actions taken:
- 扩展主 Agent 契约:目标学习者、整课目标、术语/风格/难度/考核连续性契约、模块专属提示词和输入/输出/排除知识边界。
- 严格校验新 AI 输出;新增旧课程读取兼容层,不在只读时改写旧文件。
- runner 保存提示词快照,并把完整课程契约、语言、准确时长和知识边界传入原单课件生成 requirement。
- 运营确认页展示完整主 Agent 产物;页面改用共享 API 类型并修正
id/courseId漂移。 - 为同一课程增加 runner 级互斥,并在 start/resume/framework regenerate/module regenerate 路由同步防并发。
- Files created/modified:
lib/course-framework/compat.ts(创建:旧框架读取规范化)lib/course-framework/types.ts、generate-framework.ts、runner.ts、store.tslib/prompts/templates/course-framework/system.mdapp/courses/[courseId]/page.tsxapp/api/courses/[courseId]/{start,resume,framework/regenerate,modules/[index]/regenerate}/route.tslib/i18n/locales/{zh-CN,en-US}.jsontests/course-framework/{framework,runner,store}.test.ts
Phase 3:跨模块连续性与互动生成
- Status: complete
- Started: 2026-08-15
- Actions taken:
- 新增确定性模块 output digest,从持久化的 slide/quiz/interactive/PBL Scene 与教学 Action 提取实际覆盖、互动和考核证据。
- digest 保存语义哈希;后续模块保存
continuityInputRefs并把前序实际产出注入单课件 requirement。 - 模块失败时暂停后续流水线;修复后按顺序继续,禁止跨越没有实际产出的前序模块。
- 后台单课件输入支持
interactiveMode,大型课程模块统一启用;前台与后台共用原 Interactive Mode prompt builder。 - Interactive Mode 在原子持久化前验收非空 HTML 互动 Scene,防止模型违约或内容生成失败后产出纯幻灯片。
- 运营页增加模块实际产出、语义哈希、互动与考核证据的只读查看。
- Files created/modified:
lib/course-framework/module-digest.ts(创建)lib/course-framework/types.ts、runner.ts、store.tslib/server/classroom-outline-mode.ts(创建)lib/server/classroom-generation.tsapp/api/generate-classroom/route.ts、app/api/generate/scene-outlines-stream/route.tsapp/courses/[courseId]/page.tsxlib/i18n/locales/{zh-CN,en-US}.jsontests/course-framework/{module-digest,runner,store}.test.tstests/server/{classroom-outline-mode,classroom-generation-retry}.test.ts
Phase 4:冻结发布与版本锁定
- Status: complete
- Started: 2026-08-15
- Actions taken:
- course manifest 改为保留不可覆盖的版本历史;每个模块固定
coursewareId + version + contentHash,旧 singleton 记录只读兼容并要求重新发布后才能进入学习端。 - courseware record/ZIP 改为 append-only,并在同一课件发布锁内分配版本、生成 bundle 和落库。
- learner 目录、课程页、模块入口和 loader 全链路携带精确版本/hash;下载后重算 hash、核对 bundle 身份,再使用 hash 隔离的本地 stage ID 物化。
- 冻结契约补齐 Stage 初始白板/模式、Agent persona/voice;speech 已有 bundle audioRef 时删除远端 audioUrl。
- 新增服务端 persisted classroom → frozen bundle 适配层,收集本地媒体/TTS,拒绝未解析素材,严格内联互动 HTML,复用原四类 Scene/Action 与导入器。
- 大课发布前重算每模块实际输出 digest、核对全部前序 continuity refs 和非空 HTML;打包后再次核对来源快照,再提交精确 manifest。
- 大课统一开启 TTS,确保冻结发布有持久化讲解音频。
- 并发发布和旧课程未记录连续性引用改为明确 409/未验证语义;注释明确只禁止课程生成调用,不禁用原课堂教学 Agent。
- 模块先冻结为 unpublished;全部模块和来源快照通过后统一转 published 并提交 manifest,失败时回滚本批可见状态。
- 冻结测试发现并修复
audioRef已存在时对象展开仍泄漏audioUrl的真实缺陷。
- course manifest 改为保留不可覆盖的版本历史;每个模块固定
- Files created/modified:
lib/course-manifest-repo/{types,store,index}.tslib/courseware-repo/{types,store,bundle-store,index}.tslib/server/classroom-courseware-publish.ts(创建)lib/course-framework/{publish-state,publish-validation}.ts(创建)app/api/courses/[courseId]/publish/route.tsapp/api/learn/courses/{route.ts,[courseId]/route.ts}app/api/coursewares/[id]/route.tslib/bundle/{packager,serialize,learner-load,use-publish-courseware}.tslib/export/{classroom-zip-types,classroom-zip-utils,use-export-classroom}.tslib/import/import-classroom-core.tslib/orchestration/registry/store.tslib/server/classroom-generation.tsapp/learn/{page.tsx,[coursewareId]/page.tsx,course/[courseId]/page.tsx}app/classroom/[id]/page.tsx(仅 learner 返回导航,Stage 挂载未改)app/courses/page.tsx、lib/course-framework/runner.ts
Phase 5:三端拆分准备与验收
- Status: complete
- Started: 2026-08-15
- Actions taken:
- Phase 4 合并回归通过:10 files / 85 tests,TSC 与定向 ESLint 均通过。
- 受保护课堂广泛回归执行 130 files / 1,294 tests;128 files / 1,291 tests 通过。
- 隔离复现剩余 3 个既有 Chat director 断言;文件时间和代码范围确认不由 Phase 4 产生,按保护边界不修改 Chat 内核。
- 修正 Playwright 测试服务角色:默认 E2E 显式使用 learner,不再受 development 的
allfallback 影响。 - learner 部署边界 Playwright 隔离重跑通过(1/1);首页双路径同批此前 3/3 通过。
pnpm build生产构建通过:Next.js 编译、TypeScript、51 个静态页面生成和全部大课/学习端路由收集完成。- 首轮受保护浏览器回归的 5 个失败已证明为旧 IndexedDB fixture + 残留无响应 dev server/并行干扰;迁移测试 seed 后单 worker 合并回归 11/11 通过。
- 新增真实文件仓储的大课发布边界测试 3/3:正常冻结+pin、中途失败不可见、v1 manifest 不随模块 v2 漂移。
- 完成三端架构、部署、大课模式和交接四份事实文档,明确当前单实例限制及 server → learner → ops 机械拆分顺序。
- Files created/modified:
e2e/tests/classroom-interaction.spec.ts(测试存储契约迁移)playwright.config.ts(默认 learner 角色)tests/course-framework/large-course-publish-boundary.test.ts../docs/{architecture-3-tier,deployment-3-tier,large-course-mode,handover}.md
Phase 6:独立部署边界加固
- Status: complete
- Started: 2026-08-15
- Actions taken:
- learner 任务面板已将单课件 jobs 与 ops courses 请求解耦;learner 不再探测受限 API,首页增加大课目录入口,
/publish纳入 ops gating。 - 大课 learner-facing courseware id 从 courseId+module index 稳定派生,不再泄漏可变 source classroom id;私有 source metadata 仅存于 registry,不进入公开 summary。
- learner/server 角色对已冻结发布的源 classroom JSON/媒体 fail closed;ops 仍可用源 classroom 审阅,legacy 同 id 发布记录也会被识别。
- learner 路由即使遇到异常/legacy outlines 也明确跳过 Scene/媒体生成恢复;作者课堂的中断恢复保持原行为。
- Dockerfile 在 Next build 前注入公开角色;Compose 已有 learner/ops/server 三个 build/runtime 角色一致的独立服务与数据卷。ops 生产构建实测通过并确认静态 chunk 内联
ops。 - 上游模块从任意成功/失败位置重生成时,目标及全部下游的旧 classroom/job/digest/continuity/timestamp 先原子清理,再严格顺序重建;课程立即离开 completed。
- 浏览器无显式版本 ZIP 由 server 在 publish lock 内分配 registry version 并规范化
bundle.json;learner 校验包内 version,legacy migrate 的显式 version 也传入 packager。 - ACCESS_CODE 会话现在具有统一默认 7 天 TTL、未来/过期 Token 拒绝、Cookie 同步过期、有界单进程登录限流和同源运营写请求保护。
- server 角色现在是无头服务:所有页面直接 404,运营 courses/ops/access-code API 也返回 404;内部 Bearer 发布和原课堂/单课件 API 继续交由各路由边界处理。
- ops → server 整课跨进程发布已闭环:metadata+全 ZIP 单请求、Bearer、固定目的地、上传上限、结构化错误、安全重试、本地/远端幂等语义和 publication receipt 均已落地。
- course-scoped 冻结包只在 manifest exact pin 提交后才可列表、读取和下载;存储中途失败不会给 learner 留下部分可见课程。
- 冻结哈希升级为忽略导出时间的 v2 规则,legacy v1 按旧算法验证;发布回执使用全源 revision 判断当前性。
- classroom/courseware 文件路径防穿越已收紧;课件同版本重试必须读回真实 ZIP 并核对字节/身份/归属,不存在或损坏时明确失败。
- ACCESS_CODE verify 在 JSON 解析前限制声明与实际请求体为 8 KiB;运营 CSRF 校验改用
OPS_PUBLIC_ORIGIN,不再信任 forwarded host。 - 修复课堂源与课件库路径穿越;SSRF guard 补齐 RFC6598
100.64.0.0/10,server 无头边界禁用未鉴权/api/proxy-media。 - server 继续隐藏 provider 验证、MP4 export、开发态 persistence、usage 和全局 job 列表;job DELETE 不再能删除已发布 classroom 源。
- QA/TTS 限流不再默认相信客户端 XFF,并以硬容量上限+共享 overflow bucket 避免 Map/CPU 放大;多副本共享额度仍等待 Redis/数据库/WAF。
- Phase 6 最终合并回归 26 files / 236 tests 全过,全量 TypeScript、定向 ESLint、Prettier 与 Next.js 生产构建均通过(52 个页面)。
- 独立浏览器合并回归 11/11 通过,包括原课堂切场、Roundtable、HTML iframe 保活、Quiz、播放恢复、生成跳转和 learner 部署边界。
- learner 任务面板已将单课件 jobs 与 ops courses 请求解耦;learner 不再探测受限 API,首页增加大课目录入口,
Phase 7:公网安全网络与身份边界
- Status: in_progress
- Started: 2026-08-15
- Actions taken:
- 将 Phase 6 标记为完整单实例里程碑,并把账号/owner、共享限流、数据库事务和对象存储明确迁入生产化阶段,避免把架构前置条件误报为普通收尾。
- 并行启动公网 URL safe-fetch 实现、专用 server 边界复核和 learner identity/capability 决策设计;继续冻结原互动课堂内核且不使用 DeepSeek。
- Phase 7 开始时记录受保护课堂内核聚合 SHA-256:
238041e89d96b0a2e3a187988af2e7cef97a7355775f242c35aabf42f38c7097,收口时再次计算以验证本阶段零漂移。 - 完成 learner 身份/资源授权只读设计:推荐账号主体 + 桌面设备 DPoP + exact-resource runtime grant;整理 owner、entitlement、quota、匿名数据迁移与验收矩阵,生产代码尚未在产品决策前擅自强制。
- 新增连接级 public URL fetch 与媒体代理边界:预解析结果固定到 Undici connector、逐跳重新解析与 pin、public-only 地址策略、8 KiB 请求/25 MiB 响应上限。
- safe-fetch 验证完成:安全定向 37/37、周边回归 100/100、TSC/ESLint/Prettier 与 Next.js 生产构建(52 pages)通过;live HTTPS pinned 请求 200,确认 Host/SNI 正常。
- 专用 server/发布源复核已落最小修复:GET+HEAD 全局 job list deny、Azure voice probe deny、remote current publication receipt 源反查、发布/删除 source 互斥,以及 manifest repo 自身 ID/version/path 防御;正在完成定向回归。
- 专用 server method/path 边界复核已补齐 HEAD 与尾斜杠旁路,并将 Azure voices provider 探测移出 server 公开面。
- 远程发布的当前 ops receipt 现在参与已发布 source 反查;发布/删除用同进程 source claim 消除 TOCTOU,冲突返回 409。重生后历史 source 保留语义与跨副本原子性仍明确留待持久化决策。
- course manifest 文件仓库补齐 id/version/direct-child 自校验,不再仅依赖 HTTP 路由上游的路径防穿越。
- server/source/storage 合并定向回归 18 files / 181 tests 全过,全量 TypeScript、定向 ESLint 与代码/文档 Prettier 全过。
- 主线再次独立验收:安全/发布边界 11 files / 160 tests 全过;课堂相关 87 files / 946 tests 全过;全量 TSC、定向 ESLint、Prettier 和最终 Next.js build(52 pages)通过。
- Phase 7 复验的受保护课堂聚合哈希仍为
238041e89d96b0a2e3a187988af2e7cef97a7355775f242c35aabf42f38c7097,与开始前完全一致。 - 身份基础复核确认可先做“纯策略 + generation job observe-only”竖切:resolver 当前明确 unavailable、owner 字段向后兼容可选、决策只记录不改变响应;已委派实现,强制鉴权仍等待正式账号主体决策。
- outbound safe-fetch 第二批完成:Azure voices 与 MinerU Cloud verification 使用 DNS-pinned public GET,认证头不跨重定向,helper 拒绝 Host override;为兼容本地自托管,model probe/PDF self-hosted/SDK/adapters 明确保留为后续策略迁移。
- 第二批验证:9 files / 137 tests、TSC/ESLint/Prettier 与 Next.js build(52 pages)全过。
- 身份最小竖切完成:新增 provider-neutral principal、纯 ownership policy、异常隔离的 observe-only observer,并把 generation job 的 detail/cancel/delete/resume 接入;当前 resolver 恒为 unavailable,路由响应不受 decision 影响,旧 job 无 owner 继续兼容。
- 身份竖切经独立只读审查无阻断;主线合并验证 13 files / 144 tests、全量 TSC、定向 ESLint 与最终 Next.js build(52 pages)通过。
- 完成全量 outbound 只读审计:确认 dedicated server 仍公开多条 BYOK 生成入口,旧 SSRF guard 存在 validate-then-connect DNS TOCTOU,并定位 MinerU upload/ZIP 与 Qwen audio 两条未复核 provider-returned URL 的 P0 链路。
- 下一批已按兼容性拆分并行推进:AliDoc OSS 图片 DNS pin、server-managed-only 公网 provider 门禁、MinerU 任意 method/body 二次 URL secure transport;保留桌面/运营自托管能力,不把 private provider 一刀切为 public-only。
- AliDoc OSS 图片下载已切到 DNS-pinned helper,并在连接前把 legacy HTTP URL 升级为 HTTPS;保留 OSS host allowlist、30 秒 timeout、10 MiB 声明/实际双上限和失败返回 null 语义。
- secure transport 新增有界 PUT;MinerU presigned upload 与 ZIP download、Qwen returned audio 已全部逐 URL DNS pin、拒绝 3xx、不转发 API 凭据、限制 body 并在所有路径释放 dispatcher。
- dedicated server 新增中央 managed-provider gate:unmanaged caller key/baseUrl 在 resolver 前被拒绝,server-managed 配置覆盖伪造值;desktop/ops/learner BYOK、自托管 Ollama 和本地 unpdf 保持兼容,extract-document 的 AliDoc media 直连旁路也已补齐。
- provider denial 已统一映射为稳定
403/FORBIDDEN,覆盖 image/video/TTS/voice/ASR/PDF/document/web-search 与 LLM error boundary;代表测试确认拒绝后 provider 不会被调用,非 server 成功路径不变。 - 主线最终合并回归通过:安全/身份/provider 27 files / 316 tests;大课/冻结发布 19 files / 149 tests;互动课堂相关 114 files / 1,181 tests。全量 TSC、目标 ESLint、Prettier 和 Next.js 生产 build(52 pages)全部通过。
- 本轮所有触及文件仍位于受保护课堂边界外;最近 60 分钟受保护路径无文件修改,互动课堂 1,181 项回归全绿。
- 2026-08-16 用户确认账号主体决策:正式账号作为永久 owner/权益主体,设备身份仅作持有证明或可迁移游客身份。下一步开始 owner 不可变绑定与可切换 enforcement,不在登录提供方未选定前伪造 authenticated principal。
- 新增
shadow|required身份 enforcement、账号/绑定设备/游客 subject 映射和稳定 401/403/409/503 denial;默认 shadow,真实 resolver 未安装时不会伪造账号。 - generation job create 现在可原子绑定 account owner 或 device guest;普通状态 patch 禁止修改归属。guest→account 迁移必须 compare-and-set 原 guest,legacy ownerless 还需显式 administrative opt-in,已绑定账号不可转移。
- job create/list/detail/cancel/resume/delete 已全部接入同一外围门禁:required 下 list 仅返回本人资源,精确
manage:anycapability 才可全局查看;shadow 下响应保持不变。 - 第一轮身份定向验证:6 files / 37 tests 与全量 TypeScript 通过。
Error Log
| Timestamp | Error | Attempt | Resolution |
|---|---|---|---|
| 2026-08-15 | 当前工作区不是 Git 仓库 | 1 | 采用小范围补丁、触及文件清单和逐批测试 |
| 2026-08-15 | DeepSeek Harness 未在旧任务工具清单出现 | 1 | 重启桌面应用后工具已加载并通过自检 |
| 2026-08-15 | 三个 Harness 长任务并行调用超过预期超时且无返回 | 1 | 终止并行组;下一次改用更小的串行任务,不重复同一调用方式 |
| 2026-08-15 | Prettier check 报告两个新文件格式不合规 | 1 | 运行项目 Prettier 格式化后重新验证 |
| 2026-08-15 | 运营边界首轮 TSC/发布测试/格式命令出现 3 个问题 | 1 | 已定位为残留变量、环境角色兼容和 zsh glob;采用三个独立定向修复 |
| 2026-08-15 | Prettier 对 .env.example 无可用 parser |
1 | 排除环境示例,仅格式化 TS/TSX/Markdown 支持文件 |
| 2026-08-15 | learner 部署边界 E2E 首次格式检查不通过 | 1 | 单文件 Prettier 格式化后重验 |
| 2026-08-15 | Phase 2 首次 TSC:framework AI mock 被推断为无参数函数,读取调用参数触发 TS2493 | 1 | 为 mock 显式声明 system/user 两个字符串参数后重验 |
| 2026-08-15 | Phase 2 UI 首轮 TSC/ESLint:详情类型未覆盖模块 DTO,compat 使用了 Next.js 禁用的 module 局部名 |
1 | 详情类型改为 CourseModuleView[],并把局部变量改为 moduleObj |
| 2026-08-15 | Phase 3 首轮 TSC:prompt adapter 测试的 base mock 被推断为空参数元组 | 1 | 显式声明 AICall 的 system/user/images 参数后重验 |
| 2026-08-15 | Phase 4 发布路由补丁因 import 上下文已变化而未套用 | 1 | 重新读取当前文件并以更小补丁重试成功 |
| 2026-08-15 | Phase 4 定向测试有 3 个 learner-loader 断言仍依赖旧版无哈希 fixture/stage ID | 1 | 确认为新不可变身份契约带来的测试漂移,委派更新 fixture 并补精确版本负向测试 |
| 2026-08-15 | Phase 4 计划日志补丁使用了旧版错误行文本 | 1 | 用 rg 获取精确上下文后修正补丁 |
| 2026-08-15 | Phase 4 server publish/export 测试发现 speech 序列化仍携带远端 audioUrl | 1 | 从展开对象中显式剔除 audioUrl,仅在无 bundle audioRef 时兼容回填 |
| 2026-08-15 | 受保护课堂广泛回归:130 files / 1,294 tests 中 3 个既有 Chat director 断言失败 | 1 | 其余 128 files / 1,291 tests 通过;只读诊断是否为既有 prompt/evidence 测试漂移,不修改用户要求冻结的 Chat 内核 |
| 2026-08-15 | Playwright deployment-role-boundary 在默认/复用 dev server 上看到了 ops 入口 |
1 | E2E webServer 显式固定 learner 角色;隔离重跑 1 test 通过,同批首页双路径 3 tests 此前通过 |
| 2026-08-15 | 受保护 Playwright 9 tests 并行执行时 5 tests 失败 | 1 | 3 个 beforeEach 卡在 IndexedDB seed,另有 generation redirect/scene heading 断言;改为单 worker 分组隔离,不修改课堂核心 |
| 2026-08-15 | Docker CLI 不可用,且 Next 构建打印既有 traced-file 缺失 warning | 1 | 用 YAML 契约测试 + 真实 ops pnpm build 验证角色内联;BUILD_ID/standalone 产物实际存在 |
| 2026-08-15 | 级联重生首次断言把省略的可选键当成 undefined 键 |
1 | 改为断言该键不存在,course-framework 47 tests 通过 |
| 2026-08-15 | ACCESS_CODE 加固首轮 TSC 报角色冗余分支和 WebCrypto BufferSource 类型 | 1 | 修正类型后 32 tests、TSC、ESLint 与完整构建通过 |
| 2026-08-15 | 查找 ACCESS_CODE 文档时首次使用了不存在的 README.zh-CN.md |
1 | 确认实际中文文件是 README-zh.md,对正确文件重跑检查 |
| 2026-08-15 | 更新 Phase 6 计划时首个大补丁使用了远程任务更新前的状态行 | 1 | 重读 task_plan.md,改为小范围补丁 |
| 2026-08-15 | OPS_PUBLIC_ORIGIN 首个联合补丁未匹配 .env.example 的注释形式 |
1 | 分离代码/测试与 env 补丁,按实际上下文完成 |
| 2026-08-15 | Phase 7 查看尚未落盘的 safe-fetch 文件时 zsh 未匹配 *safe* glob |
1 | 后续只用 rg --files 或显式路径读取,不重复该 glob |
| 2026-08-15 | Phase 7 主线补丁匹配了代理已经更新前的 server 复核状态行 | 1 | 重新读取当前计划/进度,保留已记录的 181 项结果并追加独立 160+946 项复验 |
| 2026-08-15 | 两个探索性的受保护哈希复算命令分别因 zsh 不拆分字符串变量和嵌套 awk 转义失败 | 1 | 不再猜测旧命令;使用已记录哈希基线、触及文件清单和受保护回归验证,本批身份竖切未进入任何受保护目录 |
| 2026-08-15 | 主线新增 AliDoc HTTP→HTTPS 用例首次格式检查失败 | 1 | 用项目 Prettier 格式化测试,随后 check 通过 |
| 2026-08-15 | Qwen 超时测试首轮较晚挂载 rejection 断言,Vitest 报 unhandled rejection | 1 | 在推进 fake timer 前先建立 rejection 断言,重跑无未处理错误 |
| 2026-08-15 | provider 扩展回归受宿主 HTTP(S)_PROXY 干扰,4 个既有 mock 请求进入真实 Undici 代理 | 1 | 清除代理环境后重跑 99 files / 773 tests 全绿,确认不是生产代码回归 |
| 2026-08-15 | 复核 extract-document 时使用了不存在的 tests/api/extract-document.test.ts |
1 | 用 rg --files 定位实际 tests/document/extract-document-route.test.ts 后完成检查 |
| 2026-08-15 | provider 403 响应测试 mock 首次使用 rest 参数,触发 TypeScript 签名不兼容 | 1 | 改为显式 route 参数签名,TSC 与全部定向测试通过 |
| 2026-08-16 | 追加账号归属发现的补丁误指工作区顶层规划文件 | 1 | 用 rg --files 确认文件位于 OpenMAIC/,改用精确绝对路径更新 |
| 2026-08-16 | 账号 owner 竖切收口时尝试 git status/diff,项目目录没有 Git 元数据 |
1 | 沿用已记录的无 Git 工作流:精确文件清单 + Prettier/ESLint/TSC + 定向回归 |
5-Question Reboot Check
- 2026-08-15 Phase 6 跨进程发布:已将 course manifest 文件仓库改为可指定目录的工厂,生产全局实例保持不变,用于隔离 server 事务测试。首个大补丁因上下文/误字失败,重读后拆小已成功。
- 2026-08-15 Phase 6 跨进程发布:已新增固定远程 origin + Bearer 的整批 multipart transport、server 单进程课程事务、实际流式上限、幂等 manifest 重试和 ops publication receipt;本地共享文件 fallback 保留。首轮 Prettier + 全量
tsc --noEmit通过。 - 2026-08-15 新增远程发布集成测试首轮:4 项中 3 项通过(成功+幂等、第二模块失败回滚、manifest 失败回滚);ops route 回执闭环返回 409,正在读取结构化错误定位。
- 2026-08-15 远程发布定向回归 5 files / 37 tests 全通过:包括真实 multipart route、两个隔离文件根、Bearer+ACCESS_CODE 并存、canonical public URL、超时安全重试、第二模块失败、manifest 失败、身份漂移、精确 learner 读取和 receipt 失效。
- 2026-08-15 远程发布专项扩展到 7/7 通过,新增非安全 HTTP/整批大小上限和 ACCESS_CODE 不能代替 Bearer 的负向用例。同一命令后的全量 TSC 被并发新增的 classroom-storage-security Stage fixture 两处类型错误阻断,已报告主线协调。
- 2026-08-15 安全重试深化发现包内 publishedAt 参与 contentHash;正在将 ops 远程打包时间固定为本次课程源快照 updatedAt,并用首次 server 成功后丢弃响应、第二次重试的集成用例验证不新增版本。
- 2026-08-15 远程安全重试已完成:集成测试首次让 server 完成发布后丢弃响应,ops 未写 receipt;第二次使用同一 source snapshot updatedAt 重新冻结,server 幂等返回 manifest v1,courseware/manifest 数量均未增加。7/7 通过。
- 2026-08-15 冻结包哈希契约升级为向后兼容 v2:新包不再让
manifest.exportedAt扰动 contentHash,远程测试改为以不同导出时间重新打包后重试,验证哈希稳定且 server 不新增版本/manifest。 - 2026-08-15 跨进程发布最终收口:幂等命中复用完整 frozen-bundle publish gate 并读取 exact 存储对象;新增大课 manifest exact-pin 公共可见性门禁;本地 fallback 复用相同事务并实现同内容 no-op。挂起 manifest 时 catalog/detail/download 均不可见,缺失/篡改 ZIP 会生成可加载的新版本。定向回归 6 files / 54 tests、全量 TSC、定向 ESLint 全通过。
- 2026-08-16 已完成课堂 owner 传递边界定位:job runner 传给
generateClassroom的 server-only options,课堂持久化包装存 owner,不将身份字段暴露给生成输入或 Stage/Scene。 - 2026-08-16 账号 owner 竖切已从 job 延伸到 raw classroom:后台生成继承 job owner,直接课堂写入保留已有 owner,required 模式限制 GET/POST,guest/legacy 迁移使用 compare-and-set;身份元数据始终位于 Stage/Scene 之外。定向 7 files / 41 tests 通过。
- 2026-08-16 账号 owner 扩展回归已通过:10 test files / 57 tests,包含 job/classroom 创建、列表、读写、迁移、路由拒绝、大课发布 learner 边界;同批 TSC 和定向 ESLint 通过。
- 2026-08-16 原课堂保护性回归通过:87 test files / 937 tests,覆盖 interactive iframe 保活、whiteboard 动作、playback 恢复、Quiz、PBL v2 和 audio/TTS。账号元数据改动未进入任何原课堂内核文件。
- 2026-08-16 账号 owner 竖切生产构建通过:Next.js 16 编译、TypeScript、52 个静态页面与全部 route 收集完成。仅有项目已存在的 middleware 命名弃用提示,无构建错误。
| Question | Answer |
|---|---|
| Where am I? | Phase 7:公网安全网络与身份边界 |
| Where am I going? | 其余 outbound safe-fetch → 产品身份决策 → owner/entitlement/quota → 数据库/对象存储 |
| What's the goal? | 不改原课堂内核,完成麦洛教育大型连续课程与三端能力边界 |
| What have I learned? | 见 findings.md |
| What have I done? | 完成大课生成/冻结/精确学习链、三角色与跨进程发布;新增 DNS-pinned 媒体代理、server/source 边界并形成 learner 身份推荐方案 |
2026-08-16 生成任务恢复专项规划
- Status: in_progress
- 阅读并遵循文件化规划流程,重新核对了当前运行状态与服务日志。
- 确认普通 Python 任务
Xjk5UcLtOx仍在推进(当时为第 5/10 个场景);英语大课程S9V3Mm0AWy在第 1 个模块因旧进程失联被判定为 stale/failed。 - 区分了“后端进程重启/失联”的证据与“无法仅凭现有日志证明具体是崩溃还是手动重启”的不确定性。
- 已将持久化任务租约、心跳、场景级检查点、大课模块续跑、旧任务兼容、故障演练和验收标准写入
task_plan.md,并将证据写入findings.md。 - 本轮没有修改生成源码、删除任务记录或中断正在运行的 Python 任务。
- Next: 按 R1 → R2 → R3 → R4 实施恢复协议,并先用故障注入和旧数据兼容测试验证,再扩大到真实生成任务。