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" ,
2026-04-18 09:38:16 +08:00
"max_tasks_per_session" : 12 ,
"max_sessions" : 120
2026-04-14 13:22:29 +08:00
},
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-18 05:43:49 +08:00
},
{
"id" : "task-008" ,
"title" : "执行 Stage P0-1:补首页/sidebar/tree shell 主链回归护栏,固化 3000 首屏、Convex live 优先与实验壳显式开关约束" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-007"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "aa6ee384" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/wolai-frontend && pnpm eslint src/hooks/use-sidebar-data.ts src/hooks/use-convex-sidebar-data.ts src/components/sidebar/sidebar.tsx src/components/sidebar/MnoteWebTreeShell.tsx && node - <<'NODE'\nconst fs = require('fs');\nconst useSidebarData = fs.readFileSync('src/hooks/use-sidebar-data.ts', 'utf8');\nconst useConvexSidebarData = fs.readFileSync('src/hooks/use-convex-sidebar-data.ts', 'utf8');\nconst sidebar = fs.readFileSync('src/components/sidebar/sidebar.tsx', 'utf8');\nconst shell = fs.readFileSync('src/components/sidebar/MnoteWebTreeShell.tsx', 'utf8');\nif (!useSidebarData.includes('!convexSidebar.hasLiveSubscription && convexSidebar.canUseHttpFallback')) throw new Error('use-sidebar-data.ts 丢失 Convex live 优先护栏');\nif (!useConvexSidebarData.includes('const hasLiveSubscription = shouldFetch')) throw new Error('use-convex-sidebar-data.ts 丢失 live subscription 判定');\nif (!sidebar.includes('runtimeConfig.mnoteWebTreeShellEnabled === true')) throw new Error('sidebar.tsx 未显式门控 tree shell');\nif (!shell.includes('readyTimerRef.current = window.setTimeout')) throw new Error('MnoteWebTreeShell.tsx 缺少超时 fallback 护栏');\nconsole.log('task-008-guardrails-ok');\nNODE\ncd /mnt/Data1T/mnote && node scripts/task097-homepage-entry-smoke.js" ,
"timeout_seconds" : 900
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已验证 Convex live 优先、tree shell 显式门控与首页 smoke; 3104 不可达时 3000 仍稳定回到 /auth。" ,
"timestamp" : "2026-04-17T15:54:10Z"
}
],
"completed_at" : "2026-04-17T15:54:10Z" ,
"claimed_by" : "SESSION-3" ,
"lease_expires_at" : "2026-04-17T16:22:02Z"
},
{
"id" : "task-009" ,
"title" : "执行 Stage P1-1:把 delete/restore/purge 收口到 shared tree command client,并让 Sidebar/DocumentContent 退出对应直调 route" ,
"status" : "completed" ,
"priority" : "P1" ,
"depends_on" : [
"task-008"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "aa6ee384" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/wolai-frontend && pnpm eslint src/lib/documents/tree-command-client.ts src/components/sidebar/sidebar.tsx src/components/editor/document-content.tsx && node - <<'NODE'\nconst fs = require('fs');\nconst client = fs.readFileSync('src/lib/documents/tree-command-client.ts', 'utf8');\nconst sidebar = fs.readFileSync('src/components/sidebar/sidebar.tsx', 'utf8');\nconst documentContent = fs.readFileSync('src/components/editor/document-content.tsx', 'utf8');\nfor (const name of ['deleteDocumentCommand', 'restoreDocumentCommand', 'purgeDocumentCommand']) {\n if (!client.includes(`export async function ${name}`)) throw new Error(`tree-command-client.ts 缺少 ${name}`);\n}\nfor (const [name, source] of [['sidebar', sidebar], ['document-content', documentContent]]) {\n if (source.includes('fetch(\"/api/documents/delete\"') || source.includes(\"fetch('/api/documents/delete'\")) throw new Error(name + ' 仍直调 /api/documents/delete');\n if (source.includes('fetch(\"/api/documents/restore\"') || source.includes(\"fetch('/api/documents/restore'\")) throw new Error(name + ' 仍直调 /api/documents/restore');\n if (source.includes('fetch(\"/api/documents/purge\"') || source.includes(\"fetch('/api/documents/purge'\")) throw new Error(name + ' 仍直调 /api/documents/purge');\n}\nconsole.log('task-009-tree-command-client-delete-restore-purge-ok');\nNODE" ,
"timeout_seconds" : 600
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已补 shared tree command client 的 delete/restore/purge,并移除 Sidebar/DocumentContent 对应 route 直调。" ,
"timestamp" : "2026-04-17T15:58:30Z"
}
],
"completed_at" : "2026-04-17T15:58:30Z" ,
"claimed_by" : "SESSION-3" ,
"lease_expires_at" : "2026-04-17T16:24:10Z"
},
{
"id" : "task-010" ,
"title" : "执行 Stage P1-2:处理 pageReference 删除路径,移除 CustomSideMenu 中对 /api/documents/delete 的直调" ,
"status" : "completed" ,
"priority" : "P1" ,
"depends_on" : [
"task-009"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "aa6ee384" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 05:43:49 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已让 CustomSideMenu 的 pageReference 删除改走 shared tree command client。" ,
"timestamp" : "2026-04-17T15:58:30Z"
}
],
2026-04-19 21:03:25 +08:00
"completed_at" : "2026-04-17T15:58:30Z"
2026-04-18 05:43:49 +08:00
},
{
"id" : "task-011" ,
"title" : "执行 Stage P1-3:为 embed 定义独立 Rust page-tree command,并让 Sidebar/DocumentContent 改走 shared embed client" ,
"status" : "completed" ,
"priority" : "P1" ,
"depends_on" : [
"task-010"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "aa6ee384" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 05:43:49 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
2026-04-19 21:03:25 +08:00
"description" : "已把 embed 收口为独立 documents.embed 命令,并补齐 TS/Rust 映射与测试。" ,
2026-04-18 05:43:49 +08:00
"timestamp" : "2026-04-17T16:15:19Z"
}
],
2026-04-19 21:03:25 +08:00
"completed_at" : "2026-04-17T16:15:19Z"
2026-04-18 05:43:49 +08:00
},
{
"id" : "task-012" ,
"title" : "执行 Stage P1-4:把 copy-tree 收口到 shared tree command client,移除 Sidebar 中文档复制的直调 route" ,
"status" : "completed" ,
"priority" : "P1" ,
"depends_on" : [
"task-011"
],
2026-04-19 21:03:25 +08:00
"attempts" : 1 ,
2026-04-18 05:43:49 +08:00
"max_attempts" : 3 ,
2026-04-19 21:03:25 +08:00
"started_at_commit" : "aa6ee384" ,
2026-04-18 05:43:49 +08:00
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 05:43:49 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已确认 copy-tree 继续走 shared tree command client 与 Rust bridge command 主链,Sidebar 不再直调 route。" ,
"timestamp" : "2026-04-17T16:15:19Z"
}
],
"completed_at" : "2026-04-17T16:15:19Z"
},
{
"id" : "task-013" ,
"title" : "执行 Stage P2-1:把 targetParentId / sortOrder / subtree move legality 收口到 Rust/bridge 主链,并补回归测试" ,
"status" : "completed" ,
"priority" : "P2" ,
"depends_on" : [
"task-012"
],
2026-04-19 21:03:25 +08:00
"attempts" : 1 ,
2026-04-18 05:43:49 +08:00
"max_attempts" : 3 ,
2026-04-19 21:03:25 +08:00
"started_at_commit" : "aa6ee384" ,
2026-04-18 05:43:49 +08:00
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 05:43:49 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已补 page-lifecycle-command-adapter 测试并收口 move/copy-tree 的 targetParentId、sortOrder 与 subtree move legality 归一化。" ,
"timestamp" : "2026-04-17T16:35:06Z"
}
],
"completed_at" : "2026-04-17T16:35:06Z"
},
{
"id" : "task-014" ,
"title" : "执行 Stage P2-2:统一 sidebar/page/file 的 kernel projection 契约,逐步移除前端本地 synthetic projection/fallback 真相" ,
"status" : "completed" ,
"priority" : "P2" ,
"depends_on" : [
"task-013"
],
2026-04-19 21:03:25 +08:00
"attempts" : 1 ,
2026-04-18 05:43:49 +08:00
"max_attempts" : 3 ,
2026-04-19 21:03:25 +08:00
"started_at_commit" : "aa6ee384" ,
2026-04-18 05:43:49 +08:00
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 05:43:49 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已移除主路径 projection fallback/synthetic projection id, sidebar/page/file 的 projection 契约改为只认上游 kernel 输出。" ,
"timestamp" : "2026-04-17T16:35:06Z"
}
],
"completed_at" : "2026-04-17T16:35:06Z"
},
{
"id" : "task-015" ,
"title" : "执行 Stage P2-3:清理 compat/fallback 与实验壳重复树拼装,确保主路径 consumer 只消费统一 projection" ,
"status" : "completed" ,
"priority" : "P2" ,
"depends_on" : [
"task-014"
],
2026-04-19 21:03:25 +08:00
"attempts" : 1 ,
2026-04-18 05:43:49 +08:00
"max_attempts" : 3 ,
2026-04-19 21:03:25 +08:00
"started_at_commit" : "aa6ee384" ,
2026-04-18 05:43:49 +08:00
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 05:43:49 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已确认 Sidebar/picker/host 主路径不再残留旧树拼装,sidebar-data 主路径不再本地合成 kernel projection。" ,
"timestamp" : "2026-04-17T16:35:06Z"
}
],
"completed_at" : "2026-04-17T16:35:06Z"
},
{
"id" : "task-016" ,
"title" : "执行 Stage P3-1:把 Rust Web SSE/WS 从 placeholder 升级为 workspace/subtree snapshot stream" ,
"status" : "completed" ,
2026-04-19 21:03:25 +08:00
"priority" : "P3" ,
2026-04-18 05:43:49 +08:00
"depends_on" : [
"task-015"
],
2026-04-19 21:03:25 +08:00
"attempts" : 1 ,
2026-04-18 05:43:49 +08:00
"max_attempts" : 3 ,
2026-04-19 21:03:25 +08:00
"started_at_commit" : "aa6ee384" ,
2026-04-18 05:43:49 +08:00
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 05:43:49 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已把 Rust Web SSE/WS 升级为 workspace/subtree snapshot stream,并复用统一 snapshot/stream support。" ,
"timestamp" : "2026-04-17T16:35:06Z"
}
],
"completed_at" : "2026-04-17T16:35:06Z"
},
{
"id" : "task-017" ,
"title" : "执行 Stage P3-2:接入 snapshot + delta + resync 协议与前端 tree stream consumer,逐步切 Sidebar/filetree/page subtree" ,
"status" : "completed" ,
2026-04-19 21:03:25 +08:00
"priority" : "P3" ,
2026-04-18 05:43:49 +08:00
"depends_on" : [
"task-016"
],
2026-04-19 21:03:25 +08:00
"attempts" : 1 ,
2026-04-18 05:43:49 +08:00
"max_attempts" : 3 ,
2026-04-19 21:03:25 +08:00
"started_at_commit" : "aa6ee384" ,
2026-04-18 05:43:49 +08:00
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 05:43:49 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已接入 useSidebarTreeStream 正式 consumer,并补齐 snapshot/delta/resync 协议与 reducer 测试。" ,
"timestamp" : "2026-04-17T16:35:06Z"
}
],
"completed_at" : "2026-04-17T16:35:06Z"
},
{
"id" : "task-018" ,
"title" : "执行 Stage P4-1:让 Rust Web 接住正式 SSR 页面壳与 server-first projection 分发,前端退回必要 islands" ,
"status" : "completed" ,
2026-04-19 21:03:25 +08:00
"priority" : "P4" ,
2026-04-18 05:43:49 +08:00
"depends_on" : [
"task-017"
],
2026-04-19 21:03:25 +08:00
"attempts" : 1 ,
2026-04-18 05:43:49 +08:00
"max_attempts" : 3 ,
2026-04-19 21:03:25 +08:00
"started_at_commit" : "aa6ee384" ,
2026-04-18 05:43:49 +08:00
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 05:43:49 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已验证 Rust Web kernel projection SSR 路由、前端 server data lint 与首页 smoke,主链仍不依赖 3104 可用。" ,
"timestamp" : "2026-04-17T16:35:06Z"
}
],
"completed_at" : "2026-04-17T16:35:06Z"
},
{
"id" : "task-019" ,
"title" : "执行 Stage QA-1:统一跑前端测试并修复必须修复的 bug,确保架构收口后的主链交互与关键回归稳定" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-018"
],
2026-04-19 21:03:25 +08:00
"attempts" : 1 ,
2026-04-18 05:43:49 +08:00
"max_attempts" : 3 ,
2026-04-19 21:03:25 +08:00
"started_at_commit" : "aa6ee384" ,
2026-04-18 05:43:49 +08:00
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 05:43:49 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已跑通前端全量测试并修复必须修复 bug:AiAgentPanel 过期断言与 tree stream 连接错误路由。" ,
"timestamp" : "2026-04-17T16:35:06Z"
}
],
"completed_at" : "2026-04-17T16:35:06Z"
},
{
"id" : "task-020" ,
"title" : "执行 Stage P4-2:回写长期架构文档与 harness 状态,勾选 design/tree-first-graph-convex-rust-long-term-architecture-v1.md 全部 checklist" ,
"status" : "completed" ,
2026-04-19 21:03:25 +08:00
"priority" : "P0" ,
2026-04-18 05:43:49 +08:00
"depends_on" : [
"task-019"
],
2026-04-19 21:03:25 +08:00
"attempts" : 1 ,
2026-04-18 05:43:49 +08:00
"max_attempts" : 3 ,
2026-04-19 21:03:25 +08:00
"started_at_commit" : "aa6ee384" ,
2026-04-18 05:43:49 +08:00
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 05:43:49 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已回写长期架构文档并清空全部 checklist,harness 状态已完成收尾。" ,
"timestamp" : "2026-04-17T16:36:54Z"
}
],
"completed_at" : "2026-04-17T16:36:54Z"
2026-04-18 09:38:16 +08:00
},
{
"id" : "task-021" ,
"title" : "执行 TreeShell Phase A-1:产出共享 tree projection contract 文档,冻结 sidebar_tree/page_tree/file_tree 共用字段与差异字段" ,
"status" : "completed" ,
2026-04-19 21:03:25 +08:00
"priority" : "P0" ,
2026-04-18 09:38:16 +08:00
"depends_on" : [
"task-020"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f1c1bcf0" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 09:38:16 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
2026-04-19 21:03:25 +08:00
"description" : "已产出共享 tree projection contract 文档,并冻结 sidebar_tree/page_tree/file_tree 的共享字段、row_id 与 resource_meta 口径。" ,
2026-04-18 09:38:16 +08:00
"timestamp" : "2026-04-17T23:18:26Z"
}
],
2026-04-19 21:03:25 +08:00
"completed_at" : "2026-04-17T23:18:26Z"
2026-04-18 09:38:16 +08:00
},
{
"id" : "task-022" ,
"title" : "执行 TreeShell Phase A-2:落地前后端共享 projection 类型,并冻结 file_tree 扩展字段与 capability/icon/resource 语义" ,
"status" : "completed" ,
2026-04-19 21:03:25 +08:00
"priority" : "P0" ,
2026-04-18 09:38:16 +08:00
"depends_on" : [
"task-021"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f1c1bcf0" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 09:38:16 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已补齐前后端共享 projection 类型与 file_tree 扩展字段,并跑通 core-protocol 与 tree-protocol 目标测试。" ,
"timestamp" : "2026-04-17T23:18:30Z"
}
],
"completed_at" : "2026-04-17T23:18:30Z"
},
{
"id" : "task-023" ,
"title" : "执行 TreeShell Phase A-3:固定树域 command protocol 长期命名面,并给出 documents.* 到 tree.* 的兼容迁移文档" ,
"status" : "completed" ,
2026-04-19 21:03:25 +08:00
"priority" : "P0" ,
2026-04-18 09:38:16 +08:00
"depends_on" : [
"task-022"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f1c1bcf0" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 09:38:16 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已冻结 tree.* 长期命名面,并把 documents.* 到 tree.* 的兼容映射与 cutover 顺序写入设计文档。" ,
"timestamp" : "2026-04-17T23:18:34Z"
}
],
"completed_at" : "2026-04-17T23:18:34Z"
},
{
"id" : "task-024" ,
"title" : "执行 TreeShell Phase A-4:明确 projection 状态与本地 UI 状态边界,并形成 Rust/前端共享的状态约束文档" ,
"status" : "completed" ,
2026-04-19 21:03:25 +08:00
"priority" : "P0" ,
2026-04-18 09:38:16 +08:00
"depends_on" : [
"task-023"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f1c1bcf0" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 09:38:16 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
2026-04-19 21:03:25 +08:00
"description" : "已固定 projection truth 与本地 UI state 的边界,并锁定 expanded、selected、focus、dragging、drop target 不进入 projection。" ,
2026-04-18 09:38:16 +08:00
"timestamp" : "2026-04-17T23:18:38Z"
}
],
"completed_at" : "2026-04-17T23:18:38Z"
},
{
"id" : "task-025" ,
"title" : "执行 TreeShell Phase A-5:补齐 projection/command protocol fixtures 与 contract tests,锁死后续 Phase B-D 的协议基线" ,
"status" : "completed" ,
2026-04-19 21:03:25 +08:00
"priority" : "P0" ,
2026-04-18 09:38:16 +08:00
"depends_on" : [
"task-024"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f1c1bcf0" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 09:38:16 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已新增 projection/command protocol contract tests,并跑通前端 fixtures 与 mnote-web tree_projection_contract 验证。" ,
"timestamp" : "2026-04-17T23:18:42Z"
}
],
"completed_at" : "2026-04-17T23:18:42Z"
},
{
"id" : "task-026" ,
"title" : "执行 TreeShell Phase B-1:在 mnote-web 补正式 sidebar_tree/page_tree/file_tree projection route 族,退出“只靠 kernel sidebar 兼容入口”阶段" ,
"status" : "completed" ,
2026-04-19 21:03:25 +08:00
"priority" : "P0" ,
2026-04-18 09:38:16 +08:00
"depends_on" : [
"task-025"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f1c1bcf0" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 09:38:16 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已补齐 mnote-web 的 sidebar/page/file projection route 族,并重新验证 tree projection routes。" ,
"timestamp" : "2026-04-18T00:38:02Z"
}
],
"completed_at" : "2026-04-18T00:38:02Z"
},
{
"id" : "task-027" ,
2026-04-19 21:03:25 +08:00
"title" : "执行 TreeShell Phase B-2:让 Rust 直接输出 file_tree projection 的 document/index/asset 行语义,前端退出同类 synthetic row 真相" ,
2026-04-18 09:38:16 +08:00
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-026"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f1c1bcf0" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 09:38:16 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "Rust 已直接输出 file_tree projection 的 document/index/asset 行语义,前端 rows 测试通过。" ,
"timestamp" : "2026-04-18T00:38:02Z"
}
],
"completed_at" : "2026-04-18T00:38:02Z"
},
{
"id" : "task-028" ,
2026-04-19 21:03:25 +08:00
"title" : "执行 TreeShell Phase B-3:继续扩充 file_tree projection 到 book/pdf/index/iconHint/capabilities,收缩前端 adapter 责任" ,
2026-04-18 09:38:16 +08:00
"status" : "completed" ,
"priority" : "P1" ,
"depends_on" : [
"task-027"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f1c1bcf0" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 09:38:16 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "Rust file_tree mapper 已扩展到 book/pdf/index/iconHint/capabilities,并验证资源变体测试。" ,
"timestamp" : "2026-04-18T00:38:02Z"
}
],
"completed_at" : "2026-04-18T00:38:02Z"
},
{
"id" : "task-029" ,
2026-04-19 21:03:25 +08:00
"title" : "执行 TreeShell Phase B-4:把树域 command 主协议切到 tree.*,保留 documents.* alias 与迁移护栏" ,
2026-04-18 09:38:16 +08:00
"status" : "completed" ,
"priority" : "P1" ,
"depends_on" : [
"task-028"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f1c1bcf0" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 09:38:16 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "树域 command 主协议已切到 tree.*,同时保留 documents.* alias 与共享 client 回归通过。" ,
"timestamp" : "2026-04-18T00:38:02Z"
}
],
"completed_at" : "2026-04-18T00:38:02Z"
},
{
"id" : "task-030" ,
2026-04-19 21:03:25 +08:00
"title" : "执行 TreeShell Phase B-5:补齐树域 route 的 trace/workspace/auth 边界与契约测试,防止主链继续依赖页面私有约定" ,
2026-04-18 09:38:16 +08:00
"status" : "completed" ,
2026-04-19 21:03:25 +08:00
"priority" : "P1" ,
2026-04-18 09:38:16 +08:00
"depends_on" : [
"task-029"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f1c1bcf0" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 09:38:16 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "树域 route 契约已补齐 trace/workspace/auth 边界,tree_route_contracts 测试通过。" ,
"timestamp" : "2026-04-18T00:38:02Z"
}
],
"completed_at" : "2026-04-18T00:38:02Z"
},
{
"id" : "task-031" ,
2026-04-19 21:03:25 +08:00
"title" : "执行 TreeShell Phase B-6:收口 Next 树域 consumer,只保留 transport/compat 边界,退出前端主路径拼树时代" ,
2026-04-18 09:38:16 +08:00
"status" : "completed" ,
"priority" : "P1" ,
"depends_on" : [
"task-030"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f1c1bcf0" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 09:38:16 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "Next 树域主路径已收口为 transport/compat, eslint 通过且 buildDocumentTree 主路径检查通过。" ,
"timestamp" : "2026-04-18T00:38:02Z"
}
],
"completed_at" : "2026-04-18T00:38:02Z"
},
{
"id" : "task-032" ,
2026-04-19 21:03:25 +08:00
"title" : "执行 TreeShell Phase C-1:为 Rust Web 正式树域 UI 壳补 Leptos scaffold、loader/dispatcher/state 骨架与 route 接缝" ,
2026-04-18 09:38:16 +08:00
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-031"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f1c1bcf0" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 09:38:16 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "mnote-web 已接入 Leptos tree shell scaffold, tree_shell 模块与 loader/dispatcher/state 骨架测试通过。" ,
"timestamp" : "2026-04-18T00:38:02Z"
}
],
"completed_at" : "2026-04-18T00:38:02Z"
},
{
"id" : "task-033" ,
2026-04-19 21:03:25 +08:00
"title" : "执行 TreeShell Phase C-2:补正式 page_tree renderer 与交互通路,打通 create/rename/move/navigate 到真实网页 smoke" ,
2026-04-18 09:38:16 +08:00
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-032"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f1c1bcf0" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 09:38:16 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "page_tree renderer 与真实网页 smoke 已跑通;task091 创建/重命名/移动/导航链路通过。" ,
"timestamp" : "2026-04-18T00:38:02Z"
}
],
"completed_at" : "2026-04-18T00:38:02Z"
},
{
"id" : "task-034" ,
2026-04-19 21:03:25 +08:00
"title" : "执行 TreeShell Phase C-3:补 selection/focus/keyboard/dragging 的本地 UI state 机理,明确不回写 projection truth" ,
2026-04-18 09:38:16 +08:00
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-033"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f1c1bcf0" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 09:38:16 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "selection/focus/keyboard/dragging 的局部 UI state 已落地并通过 Rust 测试与文档检查。" ,
"timestamp" : "2026-04-18T00:38:02Z"
}
],
"completed_at" : "2026-04-18T00:38:02Z"
},
{
"id" : "task-035" ,
"title" : "执行 TreeShell Phase C-4:补正式 tree shell 的上下文菜单、基础动作、file_tree renderer 与 picker 轻量模式" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-034"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f1c1bcf0" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 09:38:16 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "正式 tree shell 的 filetree/picker 轻量模式已补齐,新增 move-embed-picker-dialog 前端测试并通过。" ,
"timestamp" : "2026-04-18T00:38:02Z"
}
],
"completed_at" : "2026-04-18T00:38:02Z"
},
{
"id" : "task-036" ,
"title" : "执行 TreeShell Phase C-5:去掉主路径对 iframe/postMessage 实验壳的依赖,把旧 tree shell 降回 compat/debug 用途" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-035"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f1c1bcf0" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 09:38:16 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
2026-04-19 21:03:25 +08:00
"description" : "已从 sidebar.tsx 主路径移除 iframe/postMessage 实验壳依赖,Sidebar 主树回到统一 surface。" ,
2026-04-18 09:38:16 +08:00
"timestamp" : "2026-04-18T01:37:10Z"
}
],
"completed_at" : "2026-04-18T01:37:10Z" ,
"claimed_by" : "SESSION-4"
},
{
"id" : "task-037" ,
"title" : "执行 TreeShell Phase D-1:在 Next 正式挂载新 tree shell,并完成 Sidebar 主树默认切流与快速回退护栏" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-036"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "4538f85d" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 09:38:16 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
2026-04-19 21:03:25 +08:00
"description" : "已完成 Sidebar 主树默认切流与 fallback 护栏,task101 网页 smoke 通过。" ,
2026-04-18 09:38:16 +08:00
"timestamp" : "2026-04-18T01:37:10Z"
}
],
"completed_at" : "2026-04-18T01:37:10Z"
},
{
"id" : "task-038" ,
"title" : "执行 TreeShell Phase D-2:完成 filetree/page tree/picker 默认切流,并补高频路径回归 smoke" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-037"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "4538f85d" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 09:38:16 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
2026-04-19 21:03:25 +08:00
"description" : "已完成 page/filetree/picker 默认切流与高频回归,task102 与前端测试通过。" ,
2026-04-18 09:38:16 +08:00
"timestamp" : "2026-04-18T01:37:10Z"
}
],
"completed_at" : "2026-04-18T01:37:10Z"
},
{
"id" : "task-039" ,
"title" : "执行 TreeShell Phase D-3:记录树域切流性能指标与真实流量回退结果,形成 cutover/perf 报告" ,
"status" : "completed" ,
"priority" : "P1" ,
"depends_on" : [
"task-038"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "4538f85d" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 09:38:16 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
2026-04-19 21:03:25 +08:00
"description" : "已补性能报告,记录首包、首次可交互、切页延迟、大树展开延迟与 fallback。" ,
2026-04-18 09:38:16 +08:00
"timestamp" : "2026-04-18T01:37:10Z"
}
],
"completed_at" : "2026-04-18T01:37:10Z"
},
{
"id" : "task-040" ,
"title" : "执行 TreeShell Phase E-1:删除剩余 page/file 特殊拼装逻辑,继续拆分 Sidebar 超大组件,并统一 page/file/picker renderer 家族" ,
"status" : "completed" ,
"priority" : "P1" ,
"depends_on" : [
"task-039"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "4538f85d" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
2026-04-18 09:38:16 +08:00
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
2026-04-19 21:03:25 +08:00
"description" : "已统一 page/file/picker renderer surface, sidebar.tsx 不再直接耦合旧树组件名。" ,
2026-04-18 09:38:16 +08:00
"timestamp" : "2026-04-18T01:37:10Z"
}
],
"completed_at" : "2026-04-18T01:37:10Z"
},
{
"id" : "task-041" ,
"title" : "执行 Final QA:回写架构文档与 harness 状态,勾选 design/sidebar-pagetree-filetree-rust-web-rebuild-v1.md 全部 checklist 并完成最终验收" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-040"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "4538f85d" ,
"validation" : {
2026-04-19 21:03:25 +08:00
"command" : "true" ,
"timeout_seconds" : 60
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已更新设计文档 checklist 并跑通最终 smoke、pnpm test、cargo test。" ,
"timestamp" : "2026-04-18T01:37:10Z"
}
],
"completed_at" : "2026-04-18T01:37:10Z"
},
{
"id" : "task-042" ,
"title" : "执行 Kernel Phase 7-1:把文档页 pageSubtree 固化为服务端首包与 /api/documents/content 稳定响应契约,减少前端读链即时拼装" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-041"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/wolai-frontend && pnpm vitest run src/lib/documents/page-subtree-response.test.ts && pnpm eslint src/app/api/documents/content/route.ts src/app/'(app)'/documents/[id]/page.tsx src/components/editor/document-content.tsx" ,
"timeout_seconds" : 1800
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已把 pageSubtree 固化为 SSR 首包与 /api/documents/content 响应契约,并补齐共享归一化 helper 与单测。" ,
"timestamp" : "2026-04-18T02:00:05Z"
}
],
"completed_at" : "2026-04-18T02:00:05Z"
},
{
"id" : "task-043" ,
"title" : "执行 Kernel Phase 7-2:让 DocumentContent/DocumentReadView 优先消费服务端 pageSubtree,仅在本地编辑偏离后回退到前端重建" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-042"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/wolai-frontend && pnpm test && pnpm eslint src/components/editor/document-content.tsx src/components/editor/document-read-view.tsx" ,
"timeout_seconds" : 3600
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已让 DocumentContent 优先消费服务端 pageSubtree 快照,仅在标题或内容偏离服务端快照时才本地重建。" ,
"timestamp" : "2026-04-18T02:00:05Z"
}
],
"completed_at" : "2026-04-18T02:00:05Z"
},
{
"id" : "task-044" ,
"title" : "执行 Kernel Phase 7-3:补文档页 read-view/pageSubtree 回归测试,并验证 3000 首页与文档页在 3104/Convex 现状下不挂起" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-043"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote && node scripts/task097-homepage-entry-smoke.js && timeout 8s curl -fsS 'http://127.0.0.1:3000/documents/test?workspaceId=test' >/dev/null || true && cd /mnt/Data1T/mnote/wolai-frontend && pnpm vitest run src/lib/documents/page-subtree-response.test.ts" ,
"timeout_seconds" : 1800
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已补 pageSubtree 响应单测,跑通前端全量测试、首页 smoke,并确认当前 3000 主链未因 3104/Convex 挂起。" ,
"timestamp" : "2026-04-18T02:00:05Z"
}
],
"completed_at" : "2026-04-18T02:00:05Z"
},
{
"id" : "task-045" ,
"title" : "执行 Kernel Phase 7-4:把 pageSubtree/read_view 真正下沉到 bridge-runtime 与 mnote-web 输出边界,退出前端 projection 生成主路径" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-044"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/rust && cargo test -p bridge-runtime && cargo test -p mnote-web" ,
"timeout_seconds" : 3600
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 2 ,
"description" : "已为 documents.content.get 补齐 Rust page_subtree 输出、mnote-web /api/documents/content route 与对应测试,cargo test -p bridge-runtime / mnote-web 通过。" ,
"timestamp" : "2026-04-18T03:33:58Z"
},
{
"step" : 2 ,
"total" : 2 ,
"description" : "已切除前端 pageSubtree 主路径 fallback,文档页现在只消费 Rust 输出契约;pnpm vitest / pnpm test 通过。" ,
"timestamp" : "2026-04-18T03:38:08Z"
}
],
"completed_at" : "2026-04-18T03:38:08Z"
},
{
"id" : "task-046" ,
"title" : "执行 Kernel Phase 7-5:让 Next 文档页 SSR 与 /api/documents/content 优先消费 Rust 输出契约,移除前端 pageSubtree 主路径 fallback" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-045"
],
"attempts" : 0 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/wolai-frontend && pnpm eslint src/app/api/documents/content/route.ts src/app/'(app)'/documents/[id]/page.tsx src/components/editor/document-content.tsx src/components/editor/document-read-view.tsx && pnpm vitest run src/lib/documents/page-subtree-response.test.ts" ,
"timeout_seconds" : 3600
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已让 page-subtree-response、DocumentContent、DocumentReadView 退出 pageSubtree 主路径 fallback, SSR/API 只透传 Rust 输出契约。" ,
"timestamp" : "2026-04-18T03:38:08Z"
}
],
"completed_at" : "2026-04-18T03:38:08Z"
},
{
"id" : "task-047" ,
"title" : "执行 Kernel Phase 7-6:补文档页 read-view/outline/backlinks/AI context 回归,确认 read-path 收口后的读态契约稳定" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-046"
],
"attempts" : 0 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/wolai-frontend && pnpm test" ,
"timeout_seconds" : 5400
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已跑通 pnpm test,确认文档读态、outline、AI context 与现有 backlinks 面板在 read-path 收口后仍稳定。" ,
"timestamp" : "2026-04-18T03:38:08Z"
}
],
"completed_at" : "2026-04-18T03:38:08Z"
},
{
"id" : "task-048" ,
"title" : "执行 BlockEditor Phase 0-1:盘点现有 BlockNote 自定义块、读写耦合与第一阶段迁移范围,冻结必须做/后补/延期清单" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-047"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "python3 - <<'PY'\nfrom pathlib import Path\npath = Path('/mnt/Data1T/mnote/design/blocknote/rust-block-editor-phase0-baseline-v1.md')\ntext = path.read_text(encoding='utf-8')\nfor needle in ['heading', 'advancedTodo', 'pageReference', 'blockReference', 'media', 'progressMeter', 'mindmap', 'onlineTable']:\n assert needle in text, needle\nprint('task-048-phase0-baseline-ok')\nPY" ,
"timeout_seconds" : 300
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已冻结 BlockNote 自定义块、读写耦合与第一阶段迁移范围,产出 phase0 baseline 文档。" ,
"timestamp" : "2026-04-18T04:01:11Z"
}
],
"completed_at" : "2026-04-18T04:01:11Z"
},
{
"id" : "task-049" ,
"title" : "执行 BlockEditor Phase 0-2:盘点 mnote-next 交互样例并沉淀新 editor core 回归样例集,只把它当内部样本不当 benchmark" ,
"status" : "completed" ,
"priority" : "P1" ,
"depends_on" : [
"task-048"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "python3 - <<'PY'\nfrom pathlib import Path\npath = Path('/mnt/Data1T/mnote/design/blocknote/rust-block-editor-interaction-samples-v1.md')\ntext = path.read_text(encoding='utf-8')\nfor needle in ['单块编辑', '插入同级块', '空块退格合并上一块', '单块删除', '上移下移', '有限缩进', '行内页面引用', '块引用占位插入', '不作为主 benchmark']:\n assert needle in text, needle\nprint('task-049-interaction-samples-ok')\nPY" ,
"timeout_seconds" : 300
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已从 mnote-next 提取单块编辑、拆块合并、有限缩进、引用插入等内部交互样例,沉淀回归样例集。" ,
"timestamp" : "2026-04-18T04:01:11Z"
}
],
"completed_at" : "2026-04-18T04:01:11Z"
},
{
"id" : "task-050" ,
"title" : "执行 BlockEditor Phase 0-3:冻结 edita-core/blocks/kode/leptos-tiptap 采用矩阵,并把第一阶段能力边界回写主设计文档" ,
"status" : "completed" ,
"priority" : "P1" ,
"depends_on" : [
"task-049"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "python3 - <<'PY'\nfrom pathlib import Path\nmain_text = Path('/mnt/Data1T/mnote/design/blocknote/ai-first-rust-block-editor-baseline-v1.md').read_text(encoding='utf-8')\nmatrix_text = Path('/mnt/Data1T/mnote/design/blocknote/rust-block-editor-adoption-matrix-v0.md').read_text(encoding='utf-8')\nassert 'AI-first 的轻量块 Markdown 编辑器' in main_text\nassert '先复用参考层,只有缺口才自研胶水' in main_text\nfor needle in ['edita-core', 'blocks', 'kode', 'leptos-tiptap', '采用', '不采用', '部分采用']:\n assert needle in matrix_text, needle\nprint('task-050-adoption-matrix-ok')\nPY" ,
"timeout_seconds" : 300
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已冻结 edita-core/blocks/kode/leptos-tiptap 采用矩阵,并把第一阶段能力边界回写主设计文档。" ,
"timestamp" : "2026-04-18T04:01:11Z"
}
],
"completed_at" : "2026-04-18T04:01:11Z"
},
{
"id" : "task-051" ,
"title" : "执行 BlockEditor Phase 1-1:完成 edita-core 最小 spike 与适配性评估,明确 Editor/Block/Command/无头执行边界的可复用面" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-050"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "python3 - <<'PY'\nfrom pathlib import Path\ntext = Path('/mnt/Data1T/mnote/design/blocknote/rust-block-editor-edita-spike-v0.md').read_text(encoding='utf-8')\nfor needle in ['Editor', 'Block', 'Command', '无头执行', '胶水']:\n assert needle in text, needle\nprint('task-051-edita-spike-ok')\nPY" ,
"timeout_seconds" : 300
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已完成 edita-core 最小 spike 与适配性评估,明确 Editor/Block/Command/无头执行边界与胶水范围。" ,
"timestamp" : "2026-04-18T04:01:11Z"
}
],
"completed_at" : "2026-04-18T04:01:11Z"
},
{
"id" : "task-052" ,
"title" : "执行 BlockEditor Phase 1-2:完成 blocks 最小 spike 与 Markdown/history/diff-merge 适配性评估,记录可直接采用与缺口" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-051"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "python3 - <<'PY'\nfrom pathlib import Path\ntext = Path('/mnt/Data1T/mnote/design/blocknote/rust-block-editor-blocks-spike-v0.md').read_text(encoding='utf-8')\nfor needle in ['Markdown', 'round-trip', 'history', 'diff', 'merge', '缺口']:\n assert needle in text, needle\nprint('task-052-blocks-spike-ok')\nPY" ,
"timeout_seconds" : 300
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已完成 blocks 最小 spike 与 Markdown/history/diff-merge 适配性评估,记录可直接采用能力与缺口。" ,
"timestamp" : "2026-04-18T04:01:11Z"
}
],
"completed_at" : "2026-04-18T04:01:11Z"
},
{
"id" : "task-053" ,
"title" : "执行 BlockEditor Phase 1-3:定义首批 Rust block type、BlockProps、reference token 策略与 content_node 载荷格式,退出 BlockNote JSON 长期依赖" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-052"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "python3 - <<'PY'\nfrom pathlib import Path\ntext = Path('/mnt/Data1T/mnote/design/blocknote/rust-block-editor-model-v0.md').read_text(encoding='utf-8')\nfor needle in ['paragraph', 'heading', 'bullet_list_item', 'todo', 'page_reference', 'block_reference', 'BlockProps', 'content_node']:\n assert needle in text, needle\nprint('task-053-block-model-ok')\nPY" ,
"timeout_seconds" : 300
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已定义首批 Rust block type、BlockProps、reference token 策略与 content_node 载荷格式,并产出模型文档。" ,
"timestamp" : "2026-04-18T04:01:11Z"
}
],
"completed_at" : "2026-04-18T04:01:11Z"
},
{
"id" : "task-054" ,
"title" : "执行 BlockEditor Phase 1-4:定义 editor command 列表、editor 到 kernel command 映射与 Markdown import/export 边界,产出阶段 1 采用矩阵 v0" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-053"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "python3 - <<'PY'\nfrom pathlib import Path\ntext = Path('/mnt/Data1T/mnote/design/blocknote/rust-block-editor-command-contract-v0.md').read_text(encoding='utf-8')\nfor needle in ['replace_block', 'insert_block_after', 'delete_block', 'split_block', 'merge_with_previous', 'move_block', 'indent_block', 'outdent_block', 'toggle_heading_collapse', 'attach_reference_token', 'detach_reference_token', 'Markdown import', 'Markdown export']:\n assert needle in text, needle\nprint('task-054-command-contract-ok')\nPY" ,
"timeout_seconds" : 300
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已定义 editor command 列表、editor 到 kernel command 映射与 Markdown import/export 边界,产出命令契约文档。" ,
"timestamp" : "2026-04-18T04:01:11Z"
}
],
"completed_at" : "2026-04-18T04:01:11Z"
},
{
"id" : "task-055" ,
"title" : "执行 BlockEditor Phase 2-1:在 Rust workspace 搭建最小 block editor core crate,落地 block document 内存模型与只读结构树派生" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-054"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/rust && cargo test -p mnote-editor-core document_model" ,
"timeout_seconds" : 3600
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已在 Rust workspace 搭建最小 block editor core crate,落地 block document 内存模型与只读结构树派生。" ,
"timestamp" : "2026-04-18T04:01:11Z"
}
],
"completed_at" : "2026-04-18T04:01:11Z"
},
{
"id" : "task-056" ,
"title" : "执行 BlockEditor Phase 2-2:实现最小 command executor,覆盖 replace/insert/delete/split/merge/move/indent/outdent/toggle collapse" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-055"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/rust && cargo test -p mnote-editor-core command_executor" ,
"timeout_seconds" : 3600
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已实现最小 command executor,覆盖 replace/insert/delete/split/merge/move/indent/outdent/toggle collapse,并补纯 Rust 测试。" ,
"timestamp" : "2026-04-18T04:01:11Z"
}
],
"completed_at" : "2026-04-18T04:01:11Z"
},
{
"id" : "task-057" ,
"title" : "执行 BlockEditor Phase 2-3:实现 undo/redo 与 Markdown import/export,优先复用 blocks 或明确缺口清单" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-056"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/rust && cargo test -p mnote-editor-core history && cargo test -p mnote-editor-core markdown" ,
"timeout_seconds" : 3600
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已实现 undo/redo 与 Markdown import/export,优先复用最小 blocks 风格历史与转换边界,测试通过。" ,
"timestamp" : "2026-04-18T04:01:11Z"
}
],
"completed_at" : "2026-04-18T04:01:11Z"
},
{
"id" : "task-058" ,
"title" : "执行 BlockEditor Phase 2-4:补纯 Rust 回归测试与 CLI 入口,沉淀从 mnote-next 抽取的交互样例集" ,
"status" : "completed" ,
"priority" : "P1" ,
"depends_on" : [
"task-057"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/rust && cargo test -p mnote-editor-core && cargo test -p mnote-cli" ,
"timeout_seconds" : 5400
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已补纯 Rust 回归测试、CLI editor 入口,并沉淀 mnote-next 交互样例集;cargo test -p mnote-editor-core 与 cargo test -p mnote-cli 通过。" ,
"timestamp" : "2026-04-18T05:32:17Z"
}
],
"completed_at" : "2026-04-18T05:32:17Z" ,
"claimed_by" : "SESSION-9" ,
"lease_expires_at" : "2026-04-18T06:02:17Z"
},
{
"id" : "task-059" ,
"title" : "执行 BlockEditor Prototype 3-1:在 mnote-web 搭建最小 Rust 文档壳 prototype 与 feature flag,文档页先走双路径切换" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-058"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/rust && cargo test -p mnote-web && cd /mnt/Data1T/mnote/wolai-frontend && pnpm eslint src/app/'(app)'/documents/[id]/page.tsx src/components/editor/document-content.tsx" ,
"timeout_seconds" : 5400
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已在 mnote-web /document 落地最小 Rust 文档编辑壳,文档页通过 runtime flag 保持双路径切换;cargo test -p mnote-web 与 eslint 通过。" ,
"timestamp" : "2026-04-18T05:32:18Z"
}
],
"completed_at" : "2026-04-18T05:32:18Z" ,
"claimed_by" : "SESSION-9" ,
"lease_expires_at" : "2026-04-18T06:02:18Z"
},
{
"id" : "task-060" ,
"title" : "执行 BlockEditor Prototype 3-2:完成 kode/kode-leptos 策略评估,固定 block list/focus/selection/hover prototype 外壳" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-059"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/rust && cargo test -p mnote-web block_editor_shell" ,
"timeout_seconds" : 5400
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已固定 block list / focus / selection / hover 壳策略,当前采用 Rust shell + 最小 DOM 交互语义,kode 保持为块内输入器参考层;cargo test -p mnote-web block_editor_shell 通过。" ,
"timestamp" : "2026-04-18T05:32:19Z"
}
],
"completed_at" : "2026-04-18T05:32:19Z" ,
"claimed_by" : "SESSION-9" ,
"lease_expires_at" : "2026-04-18T06:02:19Z"
},
{
"id" : "task-061" ,
"title" : "执行 BlockEditor Prototype 3-3:在 document shell prototype 中落地 slash 菜单、heading 折叠、有限缩进与 [[page]]/((block)) 最小引用交互" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-060"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/rust && cargo test -p mnote-web editor_interactions && cd /mnt/Data1T/mnote/wolai-frontend && pnpm test" ,
2026-04-18 09:38:16 +08:00
"timeout_seconds" : 7200
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
2026-04-19 21:03:25 +08:00
"description" : "已落地 slash 菜单、heading 折叠、有限缩进、[[page]] / ((block)) 最小引用交互;cargo test -p mnote-web editor_interactions 与 pnpm test 通过。" ,
"timestamp" : "2026-04-18T05:32:20Z"
2026-04-18 09:38:16 +08:00
}
],
2026-04-19 21:03:25 +08:00
"completed_at" : "2026-04-18T05:32:20Z" ,
"claimed_by" : "SESSION-9" ,
"lease_expires_at" : "2026-04-18T06:02:20Z"
},
{
"id" : "task-062" ,
"title" : "执行 BlockEditor Prototype 3-4:补 prototype 浏览器回归链并确保新 UI 壳首屏不依赖 HocuspocusProvider/Yjs/comments/旧 BlockNoteView" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-061"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/wolai-frontend && pnpm test" ,
"timeout_seconds" : 7200
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已补浏览器回归链,默认新壳首屏不依赖旧 BlockNote/Yjs/comments; task103 与 pnpm test 通过。" ,
"timestamp" : "2026-04-18T05:32:21Z"
}
],
"completed_at" : "2026-04-18T05:32:21Z" ,
"claimed_by" : "SESSION-9" ,
"lease_expires_at" : "2026-04-18T06:02:21Z"
},
{
"id" : "task-063" ,
"title" : "执行 BlockEditor Phase 4-1:定义 AI/CLI 共用的 Rust editor command tool contract,禁止 AI 再模拟 DOM/UI" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-062"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "python3 - <<'PY'\nfrom pathlib import Path\ntext = Path('/mnt/Data1T/mnote/design/blocknote/rust-block-editor-ai-tool-contract-v0.md').read_text(encoding='utf-8')\nfor needle in ['insert_block_after', 'replace_block', 'delete_block', 'move_block', 'set_block_type', 'indent_block', 'outdent_block', 'toggle_heading_collapse', 'CLI', 'AI']:\n assert needle in text, needle\nprint('task-063-ai-tool-contract-ok')\nPY" ,
"timeout_seconds" : 300
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已冻结 AI/CLI 共用的 Rust editor command tool contract,并明确 AI 不再模拟 DOM/UI。" ,
"timestamp" : "2026-04-18T05:32:22Z"
}
],
"completed_at" : "2026-04-18T05:32:22Z" ,
"claimed_by" : "SESSION-9" ,
"lease_expires_at" : "2026-04-18T06:02:22Z"
},
{
"id" : "task-064" ,
"title" : "执行 BlockEditor Phase 4-2:打通纯文本导入、AI 结构化成块与按目标重写文档链路,并补 command 审计信息" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-063"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/rust && cargo test -p mnote-editor-core ai_pipeline && cargo test -p mnote-cli ai_pipeline" ,
"timeout_seconds" : 7200
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已打通纯文本导入、AI 结构化成块与按目标重写文档链路,并补齐审计与 change report; ai_pipeline 测试通过。" ,
"timestamp" : "2026-04-18T05:32:23Z"
}
],
"completed_at" : "2026-04-18T05:32:23Z" ,
"claimed_by" : "SESSION-9" ,
"lease_expires_at" : "2026-04-18T06:02:23Z"
},
{
"id" : "task-065" ,
"title" : "执行 BlockEditor Phase 4-3:补 AI 回归样例,覆盖 markdown 草稿结构化、会议记录转待办、长段落提炼标题与页面重排" ,
"status" : "completed" ,
"priority" : "P1" ,
"depends_on" : [
"task-064"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/rust && cargo test -p mnote-cli ai_regression && cd /mnt/Data1T/mnote/wolai-frontend && pnpm test" ,
"timeout_seconds" : 7200
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已补 ai_regression_* 回归样例,覆盖会议记录转待办、长段落提炼标题、页面重排;cargo test -p mnote-cli ai_regression 与 pnpm test 通过。" ,
"timestamp" : "2026-04-18T05:32:24Z"
}
],
"completed_at" : "2026-04-18T05:32:24Z" ,
"claimed_by" : "SESSION-9" ,
"lease_expires_at" : "2026-04-18T06:02:24Z"
},
{
"id" : "task-066" ,
"title" : "执行 BlockEditor Phase 5-1:盘点 BlockNote 入口、依赖与内容格式迁移策略,形成主路径退场与 compat/debug 保留方案" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-065"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "python3 - <<'PY'\nfrom pathlib import Path\ntext = Path('/mnt/Data1T/mnote/design/blocknote/rust-block-editor-blocknote-migration-v1.md').read_text(encoding='utf-8')\nfor needle in ['@blocknote/core', 'blocknote-editor.tsx', 'schema.ts', 'HocuspocusProvider', 'Yjs', 'compat', 'debug']:\n assert needle in text, needle\nprint('task-066-blocknote-migration-ok')\nPY" ,
"timeout_seconds" : 300
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已完成 BlockNote 入口、依赖与内容格式迁移策略盘点,并保留 compat/debug 方案文档。" ,
"timestamp" : "2026-04-18T05:32:25Z"
}
],
"completed_at" : "2026-04-18T05:32:25Z" ,
"claimed_by" : "SESSION-9" ,
"lease_expires_at" : "2026-04-18T06:02:25Z"
},
{
"id" : "task-067" ,
"title" : "执行 BlockEditor P0-0:冻结新的 Tiptap/Leptos/Rust 迁移基线,确认官方 notion-like 模板只作为体验 benchmark, mnote-web runtime shell 继续只保留 debug/prototype 边界" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-066"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "python3 - <<'PY2'\nfrom pathlib import Path\ntext = Path('/mnt/Data1T/mnote/design/blocknote/tiptap-leptos-rust-migration-checklist-v1.md').read_text(encoding='utf-8')\ntext2 = Path('/mnt/Data1T/mnote/design/blocknote/tiptap-notion-like-template-adoption-v1.md').read_text(encoding='utf-8')\nassert 'notion-like-editor' in text\nassert 'leptos-tiptap' in text\nassert 'runtime shell' in text\nassert '体验 benchmark' in text2\nprint('task-067-migration-baseline-frozen')\nPY2" ,
"timeout_seconds" : 600
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已冻结新的 Tiptap/Leptos/Rust 迁移基线:notion-like 模板仅作体验 benchmark, leptos-tiptap 作为运行时接入层,mnote-web runtime shell 继续只保留 debug/prototype。" ,
"timestamp" : "2026-04-18T17:51:55Z"
}
],
"claimed_by" : "SESSION-11" ,
"lease_expires_at" : null ,
"completed_at" : "2026-04-18T17:51:55Z"
},
{
"id" : "task-068" ,
"title" : "执行 BlockEditor P0-1:补齐 leptos-tiptap 的 task_list/task_item Rust 暴露、运行时注册与 spike 真 schema 验证,替换当前 todo HTML 占位" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-067"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/rust && cargo +1.89.0 check --manifest-path /mnt/Data1T/mnote/rust/spikes/leptos-tiptap-spike/Cargo.toml && cd /mnt/Data1T/mnote/rust/spikes/leptos-tiptap-spike && env -u NO_COLOR trunk build --release && node - <<'NODE'\nconst fs = require('fs');\nconst cargo = fs.readFileSync('/mnt/Data1T/mnote/design/blocknote/reference-code/leptos-tiptap/Cargo.toml', 'utf8');\nconst ext = fs.readFileSync('/mnt/Data1T/mnote/design/blocknote/reference-code/leptos-tiptap/src/api/extensions.rs', 'utf8');\nconst ffi = fs.readFileSync('/mnt/Data1T/mnote/design/blocknote/reference-code/leptos-tiptap/src/runtime/ffi.rs', 'utf8');\nconst reg = fs.readFileSync('/mnt/Data1T/mnote/design/blocknote/reference-code/leptos-tiptap/src/runtime/registration.rs', 'utf8');\nif (!cargo.includes('task_item') || !cargo.includes('task_list')) throw new Error('Cargo features 未补 task_list/task_item');\nif (!ext.includes('TaskItem') || !ext.includes('TaskList')) throw new Error('extensions.rs 未暴露 TaskItem/TaskList');\nif (!ffi.includes('register_task_item') || !ffi.includes('register_task_list')) throw new Error('ffi.rs 未暴露 task 注册');\nif (!reg.includes('register_task_item') || !reg.includes('register_task_list')) throw new Error('registration.rs 未注册 task 扩展');\nconsole.log('task-068-tasklist-bridge-ok');\nNODE" ,
"timeout_seconds" : 10800
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已补齐 leptos-tiptap 的 task_list/task_item Rust 暴露与运行时注册,修复 list_item/task_item 命令冲突,并在 8123 spike 页面通过网页 smoke 验证 taskList/taskItem 真 schema。" ,
"timestamp" : "2026-04-18T17:51:55Z"
}
],
"completed_at" : "2026-04-18T17:51:55Z"
},
{
"id" : "task-069" ,
"title" : "执行 BlockEditor P0-2:把 leptos-tiptap spike 从调试展示页推进为最小产品页壳,去掉重 debug 侧栏布局,保留真实 Tiptap surface 与常用块体验" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-068"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/rust && cargo +1.89.0 check --manifest-path /mnt/Data1T/mnote/rust/spikes/leptos-tiptap-spike/Cargo.toml && cd /mnt/Data1T/mnote/rust/spikes/leptos-tiptap-spike && env -u NO_COLOR trunk build --release" ,
"timeout_seconds" : 7200
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已把 leptos-tiptap spike 收敛为最小产品页壳:主视觉切到单页编辑体验,调试输出降为折叠抽屉,不再以双栏 debug panel 作为主界面。" ,
"timestamp" : "2026-04-18T17:51:55Z"
}
],
"completed_at" : "2026-04-18T17:51:55Z"
},
{
"id" : "task-070" ,
"title" : "执行 BlockEditor P0-3:按官方 notion-like 模板交互模型实现最小 slash 菜单,只保留 paragraph、heading1/2/3、bullet、ordered、todo、blockquote、code block、divider" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-069"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/rust && cargo +1.89.0 check --manifest-path /mnt/Data1T/mnote/rust/spikes/leptos-tiptap-spike/Cargo.toml && python3 - <<'PY2'\nfrom pathlib import Path\ntext = Path('/mnt/Data1T/mnote/rust/spikes/leptos-tiptap-spike/src/main.rs').read_text(encoding='utf-8')\nfor needle in ['heading', 'blockquote', 'code block', 'Todo', 'Slash']:\n assert needle.lower() in text.lower(), needle\nprint('task-070-slash-minimal-ok')\nPY2" ,
"timeout_seconds" : 7200
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已在 8123 spike 实现真正由 “/” 触发的最小 slash 菜单,覆盖 paragraph、heading1/2/3、bullet、ordered、todo、blockquote、code block、divider,并通过网页 smoke。" ,
"timestamp" : "2026-04-18T17:51:55Z"
}
],
"completed_at" : "2026-04-18T17:51:55Z"
},
{
"id" : "task-071" ,
"title" : "执行 BlockEditor P0-4:按官方 notion-like 模板交互模型实现最小浮动工具条,保留 bold、italic、strike、code、link、highlight、turn into、undo/redo" ,
"status" : "completed" ,
"priority" : "P0" ,
"depends_on" : [
"task-070"
],
"attempts" : 1 ,
"max_attempts" : 3 ,
"started_at_commit" : "f9a45e89" ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/rust && cargo +1.89.0 check --manifest-path /mnt/Data1T/mnote/rust/spikes/leptos-tiptap-spike/Cargo.toml && python3 - <<'PY2'\nfrom pathlib import Path\ntext = Path('/mnt/Data1T/mnote/rust/spikes/leptos-tiptap-spike/src/main.rs').read_text(encoding='utf-8')\nfor needle in ['bold', 'italic', 'strike', 'highlight', 'undo', 'redo']:\n assert needle.lower() in text.lower(), needle\nprint('task-071-floating-toolbar-minimal-ok')\nPY2" ,
"timeout_seconds" : 7200
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : [
{
"step" : 1 ,
"total" : 1 ,
"description" : "已在 8123 spike 实现最小浮动工具条并以常驻方式先打通 P0 验证链,包含 bold、italic、strike、code、link、highlight、turn into、undo/redo,网页 smoke 通过。" ,
"timestamp" : "2026-04-18T17:51:55Z"
}
],
"completed_at" : "2026-04-18T17:51:55Z"
},
{
"id" : "task-072" ,
"title" : "执行 BlockEditor P0-5:明确并打通 Tiptap JSON 到 Rust 文档真相的保存边界,禁止引入 runtime shell 专用格式,并完成 reload 不丢结构" ,
"status" : "pending" ,
"priority" : "P0" ,
"depends_on" : [
"task-071"
],
"attempts" : 0 ,
"max_attempts" : 3 ,
"started_at_commit" : null ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/rust && cargo test -p mnote-web && python3 - <<'PY2'\nfrom pathlib import Path\ntext = Path('/mnt/Data1T/mnote/design/blocknote/tiptap-leptos-rust-migration-checklist-v1.md').read_text(encoding='utf-8')\nassert 'Tiptap JSON 作为运行时输入,Rust 侧导出统一文档真相' in text\nprint('task-072-save-boundary-doc-ok')\nPY2" ,
"timeout_seconds" : 10800
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : []
},
{
"id" : "task-073" ,
"title" : "执行 BlockEditor P0-6:对齐 EditorBlockType 与 P0 schema,至少覆盖 Paragraph、Heading、BulletListItem、NumberedListItem、Todo、Quote、CodeBlock" ,
"status" : "pending" ,
"priority" : "P0" ,
"depends_on" : [
"task-072"
],
"attempts" : 0 ,
"max_attempts" : 3 ,
"started_at_commit" : null ,
"validation" : {
"command" : "python3 - <<'PY2'\nfrom pathlib import Path\ntext = Path('/mnt/Data1T/mnote/rust/crates/core-protocol/src/editor/model.rs').read_text(encoding='utf-8')\nfor needle in ['Paragraph', 'Heading', 'BulletListItem', 'NumberedListItem', 'Todo', 'Quote', 'CodeBlock']:\n assert needle in text, needle\nprint('task-073-editor-blocktype-p0-ok')\nPY2" ,
"timeout_seconds" : 1200
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : []
},
{
"id" : "task-074" ,
"title" : "执行 BlockEditor P0-7:对齐 EditorCommand 与 P0 交互,至少覆盖 split、merge、insert、replace、indent/outdent 与保存级 toggle heading collapse 语义" ,
"status" : "pending" ,
"priority" : "P0" ,
"depends_on" : [
"task-073"
],
"attempts" : 0 ,
"max_attempts" : 3 ,
"started_at_commit" : null ,
"validation" : {
"command" : "python3 - <<'PY2'\nfrom pathlib import Path\ntext = Path('/mnt/Data1T/mnote/rust/crates/core-protocol/src/editor/command.rs').read_text(encoding='utf-8')\nfor needle in ['Split', 'Merge', 'Insert', 'Replace', 'Indent', 'Outdent', 'ToggleHeadingCollapse']:\n assert needle in text, needle\nprint('task-074-editor-command-p0-ok')\nPY2" ,
"timeout_seconds" : 1200
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : []
},
{
"id" : "task-075" ,
"title" : "执行 BlockEditor P0-8:用真实网页回归验证 P0 主编辑器最小可写闭环,标准改为接近 Tiptap/Wolai 页面体验,而不是 shell 标题加 textarea" ,
"status" : "pending" ,
"priority" : "P0" ,
"depends_on" : [
"task-074"
],
"attempts" : 0 ,
"max_attempts" : 3 ,
"started_at_commit" : null ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/wolai-frontend && pnpm test && cd /mnt/Data1T/mnote/rust && cargo test && python3 - <<'PY2'\nfrom pathlib import Path\ntext = Path('/mnt/Data1T/mnote/design/blocknote/tiptap-leptos-rust-migration-checklist-v1.md').read_text(encoding='utf-8')\nassert '不是 runtime shell' in text\nassert '不是 textarea 壳' in text\nprint('task-075-p0-qa-baseline-ok')\nPY2" ,
"timeout_seconds" : 14400
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : []
},
{
"id" : "task-076" ,
"title" : "执行 BlockEditor P1-1:引入稳定 block id 策略与 UniqueID 对齐,为引用、拖拽、局部更新和审计打基础" ,
"status" : "pending" ,
"priority" : "P1" ,
"depends_on" : [
"task-075"
],
"attempts" : 0 ,
"max_attempts" : 3 ,
"started_at_commit" : null ,
"validation" : {
"command" : "python3 - <<'PY2'\nfrom pathlib import Path\ntext = Path('/mnt/Data1T/mnote/design/blocknote/tiptap-leptos-rust-migration-checklist-v1.md').read_text(encoding='utf-8')\nassert '稳定 block id' in text\nassert 'UniqueID' in text\nprint('task-076-block-id-plan-ok')\nPY2" ,
"timeout_seconds" : 600
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : []
},
{
"id" : "task-077" ,
"title" : "执行 BlockEditor P1-2:增加普通块缩进、页面引用/块引用、拖拽块 handle、块菜单与 turn into,按官方 notion-like 交互分类做 Leptos 自建桥接" ,
"status" : "pending" ,
"priority" : "P1" ,
"depends_on" : [
"task-076"
],
"attempts" : 0 ,
"max_attempts" : 3 ,
"started_at_commit" : null ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/rust && cargo test -p mnote-web && python3 - <<'PY2'\nfrom pathlib import Path\ntext = Path('/mnt/Data1T/mnote/design/blocknote/tiptap-leptos-rust-migration-checklist-v1.md').read_text(encoding='utf-8')\nfor needle in ['缩进', '页面引用 / 块引用', '拖拽块 handle', 'Turn Into']:\n assert needle in text, needle\nprint('task-077-p1-interactions-plan-ok')\nPY2" ,
"timeout_seconds" : 10800
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : []
},
{
"id" : "task-078" ,
"title" : "执行 BlockEditor P1-3:增加 Markdown 导入导出回归、heading collapse 树语义对齐,并完成新的正式主编辑器阶段 QA" ,
"status" : "pending" ,
"priority" : "P1" ,
"depends_on" : [
"task-077"
],
"attempts" : 0 ,
"max_attempts" : 3 ,
"started_at_commit" : null ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/rust && cargo test -p mnote-editor-core && cargo test -p mnote-web && cd /mnt/Data1T/mnote/wolai-frontend && pnpm test" ,
"timeout_seconds" : 14400
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : []
},
{
"id" : "task-079" ,
"title" : "执行 BlockEditor P2-1:接入 Rust outline projection 驱动目录、图片/附件桥接、轻量表格评估、移动端工具条与 Rust AI 命令入口" ,
"status" : "pending" ,
"priority" : "P2" ,
"depends_on" : [
"task-078"
],
"attempts" : 0 ,
"max_attempts" : 3 ,
"started_at_commit" : null ,
"validation" : {
"command" : "python3 - <<'PY2'\nfrom pathlib import Path\ntext = Path('/mnt/Data1T/mnote/design/blocknote/tiptap-leptos-rust-migration-checklist-v1.md').read_text(encoding='utf-8')\nfor needle in ['outline projection', '图片块与附件桥接', '移动端工具条', 'AI 编辑命令入口']:\n assert needle in text, needle\nprint('task-079-p2-plan-ok')\nPY2" ,
"timeout_seconds" : 600
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : []
},
{
"id" : "task-080" ,
"title" : "执行 BlockEditor Cleanup:在 P0/P1 主编辑器稳定后,再清理 BlockNote/Yjs/Mantine 依赖、旧自定义块主线耦合,并在最后统一协调 3000/3104/Convex 接入边界" ,
"status" : "pending" ,
"priority" : "P1" ,
"depends_on" : [
"task-078"
],
"attempts" : 0 ,
"max_attempts" : 3 ,
"started_at_commit" : null ,
"validation" : {
"command" : "cd /mnt/Data1T/mnote/wolai-frontend && pnpm test && pnpm lint && cd /mnt/Data1T/mnote && node scripts/task097-homepage-entry-smoke.js" ,
"timeout_seconds" : 14400
},
"on_failure" : {
"cleanup" : null
},
"error_log" : [],
"checkpoints" : []
2026-04-15 03:34:52 +08:00
}
],
2026-04-19 21:03:25 +08:00
"session_count" : 11 ,
"last_session" : "2026-04-18T17:51:55Z"
2026-04-14 13:22:29 +08:00
}