2026-04-14 13:22:29 +08:00
{
"version" : 2 ,
2026-04-17 23:36:24 +08:00
"created" : "2026-04-17T07:58:16Z" ,
2026-04-14 13:22:29 +08:00
"session_config" : {
"concurrency_mode" : "exclusive" ,
"max_tasks_per_session" : 20 ,
"max_sessions" : 50
},
2026-04-15 03:34:52 +08:00
"tasks" : [
{
"id" : "task-001" ,
2026-04-17 23:36:24 +08:00
"title" : "执行 Stage A-1:固定首页与 /api/sidebar 主路径只走 Convex/Rust 主链,禁止默认回落到 mnote-web compat/sidebar,并把 tree shell 默认运行态切成显式开关" ,
2026-04-15 20:01:12 +08:00
"status" : "completed" ,
2026-04-17 23:36:24 +08:00
"priority" : "P0" ,
2026-04-15 03:34:52 +08:00
"depends_on" : [],
"attempts" : 1 ,
2026-04-17 23:36:24 +08:00
"max_attempts" : 3 ,
"started_at_commit" : "4538f85d" ,
2026-04-15 03:34:52 +08:00
"validation" : {
2026-04-17 23:36:24 +08:00
"command" : "cd /mnt/Data1T/mnote/wolai-frontend && pnpm eslint src/app/api/sidebar/route.ts src/lib/runtime-config.ts src/components/sidebar/sidebar.tsx src/components/sidebar/MnoteWebTreeShell.tsx && node - <<'NODE'\nconst fs = require('fs');\nconst route = fs.readFileSync('src/app/api/sidebar/route.ts', 'utf8');\nconst runtime = fs.readFileSync('src/lib/runtime-config.ts', 'utf8');\nconst sidebar = fs.readFileSync('src/components/sidebar/sidebar.tsx', 'utf8');\nconst shell = fs.readFileSync('src/components/sidebar/MnoteWebTreeShell.tsx', 'utf8');\nconst envJson = JSON.parse(fs.readFileSync('public/mnote-env.json', 'utf8'));\nif (/fetchSidebarDatasetFromMnoteWeb|getMnoteWebBaseUrl\\(/.test(route)) throw new Error('route.ts 仍残留 mnote-web compat 主路径');\nif (!runtime.includes('parseRuntimeBoolean(cfg.mnoteWebTreeShellEnabled) ?? false')) throw new Error('runtime-config.ts 未把 tree shell 默认值固定为 false');\nif (!sidebar.includes('mnoteWebTreeShellEnabled === true')) throw new Error('sidebar.tsx 未收紧为显式开关');\nif (!shell.includes('mnoteWebTreeShellEnabled === true')) throw new Error('MnoteWebTreeShell.tsx 未收紧为显式开关');\nif (envJson.mnoteWebTreeShellEnabled !== false) throw new Error('public/mnote-env.json 未默认关闭 tree shell');\nconsole.log('task-001-boundary-ok');\nNODE" ,
"timeout_seconds" : 300
2026-04-15 03:34:52 +08:00
},
"on_failure" : {
"cleanup" : null
},
2026-04-17 23:36:24 +08:00
"error_log" : [],
"checkpoints" : [],
"completed_at" : "2026-04-17T08:03:15Z"
2026-04-15 03:34:52 +08:00
},
{
"id" : "task-002" ,
2026-04-17 23:36:24 +08:00
"title" : "执行 Stage A-2:收紧 move/embed picker 的实验壳边界,tree shell 关闭时不再额外请求 viewer/tree-shell 依赖,空查询路径继续只消费稳定 projection 数据" ,
2026-04-15 03:34:52 +08:00
"status" : "completed" ,
"priority" : "P0" ,
2026-04-17 23:36:24 +08:00
"depends_on" : [
"task-001"
],
2026-04-15 03:34:52 +08:00
"attempts" : 1 ,
"max_attempts" : 3 ,
2026-04-17 23:36:24 +08:00
"started_at_commit" : "4538f85d" ,
2026-04-15 03:34:52 +08:00
"validation" : {
2026-04-17 23:36:24 +08:00
"command" : "cd /mnt/Data1T/mnote/wolai-frontend && pnpm eslint src/components/documents/move-embed-picker-dialog.tsx src/components/documents/move-embed-picker-host.tsx && node - <<'NODE'\nconst fs = require('fs');\nconst dialog = fs.readFileSync('src/components/documents/move-embed-picker-dialog.tsx', 'utf8');\nif (!dialog.includes('const treeShellEnabled =')) throw new Error('picker 未显式计算 treeShellEnabled');\nif (!dialog.includes('enabled: Boolean(workspaceId) && isEmptyQuery && treeShellEnabled')) throw new Error('viewerQuery 仍会在 tree shell 关闭时触发');\nconsole.log('task-002-picker-boundary-ok');\nNODE" ,
"timeout_seconds" : 300
2026-04-15 03:34:52 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
2026-04-17 23:36:24 +08:00
"checkpoints" : [],
"completed_at" : "2026-04-17T08:06:06Z"
2026-04-15 03:34:52 +08:00
},
{
"id" : "task-003" ,
2026-04-17 23:36:24 +08:00
"title" : "执行 Stage A-3:新增并跑通 3000 首页入口 smoke,验证在 3104 不可用时首页主链仍可进入 /auth 或已登录文档页,不因实验壳阻塞" ,
2026-04-15 03:34:52 +08:00
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
2026-04-17 23:36:24 +08:00
"task-001" ,
2026-04-15 03:34:52 +08:00
"task-002"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
2026-04-17 23:36:24 +08:00
"started_at_commit" : "4538f85d" ,
2026-04-15 03:34:52 +08:00
"validation" : {
2026-04-17 23:36:24 +08:00
"command" : "cd /mnt/Data1T/mnote && node scripts/task097-homepage-entry-smoke.js" ,
"timeout_seconds" : 600
2026-04-15 03:34:52 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
2026-04-17 23:36:24 +08:00
"checkpoints" : [],
"completed_at" : "2026-04-17T08:12:27Z"
2026-04-15 03:34:52 +08:00
},
{
"id" : "task-004" ,
2026-04-17 23:36:24 +08:00
"title" : "执行 Stage B-1:继续收缩前端树域真相泄漏,确认主路径 consumer 只消费 kernel projection,兼容 helper 不再回到运行时主链" ,
2026-04-15 03:34:52 +08:00
"status" : "completed" ,
"priority" : "P1" ,
"depends_on" : [
2026-04-17 23:36:24 +08:00
"task-001" ,
2026-04-15 03:34:52 +08:00
"task-002"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
2026-04-17 23:36:24 +08:00
"started_at_commit" : "4538f85d" ,
2026-04-15 03:34:52 +08:00
"validation" : {
2026-04-17 23:36:24 +08:00
"command" : "cd /mnt/Data1T/mnote/wolai-frontend && pnpm eslint src/components/sidebar/sidebar.tsx src/components/documents/move-embed-picker-dialog.tsx src/components/documents/move-embed-picker-host.tsx && node - <<'NODE'\nconst fs = require('fs');\nconst sidebar = fs.readFileSync('src/components/sidebar/sidebar.tsx', 'utf8');\nconst picker = fs.readFileSync('src/components/documents/move-embed-picker-dialog.tsx', 'utf8');\nconst host = fs.readFileSync('src/components/documents/move-embed-picker-host.tsx', 'utf8');\nfor (const [name, source] of [['sidebar', sidebar], ['picker', picker], ['host', host]]) {\n if (source.includes('buildDocumentTree(')) throw new Error(name + ' 仍残留 buildDocumentTree 主路径依赖');\n}\nconsole.log('task-004-tree-truth-mainpath-ok');\nNODE" ,
"timeout_seconds" : 300
2026-04-15 03:34:52 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
2026-04-17 23:36:24 +08:00
"checkpoints" : [],
"completed_at" : "2026-04-17T08:11:55Z"
2026-04-15 03:34:52 +08:00
},
{
"id" : "task-005" ,
2026-04-17 23:36:24 +08:00
"title" : "执行 Stage B-2:梳理 sidebar/page/filetree 的 create/rename/move 命令入口,给出并落第一批 Rust command envelope 收口边界,避免前端继续扩散树语义" ,
2026-04-15 03:34:52 +08:00
"status" : "completed" ,
"priority" : "P1" ,
"depends_on" : [
2026-04-17 23:36:24 +08:00
"task-004"
2026-04-15 03:34:52 +08:00
],
"attempts" : 1 ,
"max_attempts" : 3 ,
2026-04-17 23:36:24 +08:00
"started_at_commit" : "4538f85d" ,
2026-04-15 03:34:52 +08:00
"validation" : {
2026-04-17 23:36:24 +08:00
"command" : "python3 - <<'PY'\nfrom pathlib import Path\nroot = Path('/mnt/Data1T/mnote')\npath = root / 'design/tree-command-envelope-cutover-stage1-v1.md'\ntext = path.read_text(encoding='utf-8')\nassert 'sidebar.tsx' in text\nassert 'create / rename / move' in text or 'create/rename/move' in text\nprint('task-005-command-cutover-doc-ok')\nPY" ,
"timeout_seconds" : 120
2026-04-15 03:34:52 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 2 ,
2026-04-17 23:36:24 +08:00
"description" : "已审计 sidebar/document-content/CustomSideMenu 与 create/title/move route,确认第一批 tree command 已接入 envelope,但入口与部分树策略仍散落在前端组件层。" ,
"timestamp" : "2026-04-17T08:32:00Z"
2026-04-15 03:34:52 +08:00
},
{
"step" : 2 ,
"total" : 2 ,
2026-04-17 23:36:24 +08:00
"description" : "已新增共享 tree command client,并产出 design/tree-command-envelope-cutover-stage1-v1.md 固定第一批 cutover 边界与顺序。" ,
"timestamp" : "2026-04-17T08:40:10Z"
2026-04-15 03:34:52 +08:00
}
],
2026-04-17 23:36:24 +08:00
"completed_at" : "2026-04-17T08:40:10Z"
2026-04-15 03:34:52 +08:00
},
{
"id" : "task-006" ,
2026-04-17 23:36:24 +08:00
"title" : "执行 Stage C-1:为 Rust Web 正式实时树事件流补方案与接缝说明,明确 Convex substrate 与 Rust semantic owner 的订阅职责划分" ,
2026-04-15 03:34:52 +08:00
"status" : "completed" ,
2026-04-17 23:36:24 +08:00
"priority" : "P2" ,
2026-04-15 03:34:52 +08:00
"depends_on" : [
2026-04-17 23:36:24 +08:00
"task-003" ,
2026-04-15 03:34:52 +08:00
"task-005"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
2026-04-17 23:36:24 +08:00
"started_at_commit" : "4538f85d" ,
2026-04-15 03:34:52 +08:00
"validation" : {
2026-04-17 23:36:24 +08:00
"command" : "python3 - <<'PY'\nfrom pathlib import Path\nroot = Path('/mnt/Data1T/mnote')\npath = root / 'design/rust-web-tree-realtime-event-stream-v1.md'\ntext = path.read_text(encoding='utf-8')\nassert 'Convex substrate' in text or 'Convex' in text\nassert 'Rust semantic owner' in text or 'Rust' in text\nprint('task-006-realtime-doc-ok')\nPY" ,
"timeout_seconds" : 120
2026-04-15 03:34:52 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
2026-04-17 23:36:24 +08:00
"total" : 1 ,
"description" : "已产出 design/rust-web-tree-realtime-event-stream-v1.md,明确 Convex substrate、Rust semantic owner、Rust Web SSE/WS transport 与前端 projection consumer 的职责划分。" ,
"timestamp" : "2026-04-17T08:42:00Z"
2026-04-15 03:34:52 +08:00
}
],
2026-04-17 23:36:24 +08:00
"completed_at" : "2026-04-17T08:42:00Z"
2026-04-15 03:34:52 +08:00
},
{
"id" : "task-007" ,
2026-04-17 23:36:24 +08:00
"title" : "执行 Stage C-2:回写新的 harness 批次状态、阶段完成度与长期口径,明确哪些已进入稳定主链,哪些仍属于实验壳/后续阶段" ,
2026-04-15 03:34:52 +08:00
"status" : "completed" ,
"priority" : "P1" ,
"depends_on" : [
"task-003" ,
"task-004" ,
"task-005" ,
"task-006"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
2026-04-17 23:36:24 +08:00
"started_at_commit" : "4538f85d" ,
2026-04-15 03:34:52 +08:00
"validation" : {
2026-04-17 23:36:24 +08:00
"command" : "python3 - <<'PY'\nfrom pathlib import Path\nroot = Path('/mnt/Data1T/mnote')\nassert (root / 'harness-tasks.json').exists()\nassert (root / 'harness-progress.txt').exists()\nprint('task-007-harness-sync-ok')\nPY" ,
2026-04-15 03:34:52 +08:00
"timeout_seconds" : 120
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
2026-04-17 23:36:24 +08:00
"description" : "已回写 harness 状态与进度,并验证修复 dev server 的 Convex HTTP 代理后,3000 首页基线恢复:/auth 返回 200,/ 根路径稳定进入 /auth。" ,
"timestamp" : "2026-04-17T08:56:30Z"
2026-04-15 03:34:52 +08:00
}
],
2026-04-17 23:36:24 +08:00
"completed_at" : "2026-04-17T08:56:30Z"
2026-04-15 03:34:52 +08:00
}
],
2026-04-17 23:36:24 +08:00
"session_count" : 2 ,
"last_session" : "2026-04-17T08:56:30Z"
2026-04-14 13:22:29 +08:00
}