Files
mnote/harness-tasks.json
T

2275 lines
85 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"version": 2,
"created": "2026-04-17T07:58:16Z",
"session_config": {
"concurrency_mode": "exclusive",
"max_tasks_per_session": 12,
"max_sessions": 120
},
"tasks": [
{
"id": "task-001",
"title": "执行 Stage A-1:固定首页与 /api/sidebar 主路径只走 Convex/Rust 主链,禁止默认回落到 mnote-web compat/sidebar,并把 tree shell 默认运行态切成显式开关",
"status": "completed",
"priority": "P0",
"depends_on": [],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "4538f85d",
"validation": {
"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
},
"on_failure": {
"cleanup": null
},
"error_log": [],
"checkpoints": [],
"completed_at": "2026-04-17T08:03:15Z"
},
{
"id": "task-002",
"title": "执行 Stage A-2:收紧 move/embed picker 的实验壳边界,tree shell 关闭时不再额外请求 viewer/tree-shell 依赖,空查询路径继续只消费稳定 projection 数据",
"status": "completed",
"priority": "P0",
"depends_on": [
"task-001"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "4538f85d",
"validation": {
"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
},
"on_failure": {
"cleanup": null
},
"error_log": [],
"checkpoints": [],
"completed_at": "2026-04-17T08:06:06Z"
},
{
"id": "task-003",
"title": "执行 Stage A-3:新增并跑通 3000 首页入口 smoke,验证在 3104 不可用时首页主链仍可进入 /auth 或已登录文档页,不因实验壳阻塞",
"status": "completed",
"priority": "P0",
"depends_on": [
"task-001",
"task-002"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "4538f85d",
"validation": {
"command": "cd /mnt/Data1T/mnote && node scripts/task097-homepage-entry-smoke.js",
"timeout_seconds": 600
},
"on_failure": {
"cleanup": null
},
"error_log": [],
"checkpoints": [],
"completed_at": "2026-04-17T08:12:27Z"
},
{
"id": "task-004",
"title": "执行 Stage B-1:继续收缩前端树域真相泄漏,确认主路径 consumer 只消费 kernel projection,兼容 helper 不再回到运行时主链",
"status": "completed",
"priority": "P1",
"depends_on": [
"task-001",
"task-002"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "4538f85d",
"validation": {
"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
},
"on_failure": {
"cleanup": null
},
"error_log": [],
"checkpoints": [],
"completed_at": "2026-04-17T08:11:55Z"
},
{
"id": "task-005",
"title": "执行 Stage B-2:梳理 sidebar/page/filetree 的 create/rename/move 命令入口,给出并落第一批 Rust command envelope 收口边界,避免前端继续扩散树语义",
"status": "completed",
"priority": "P1",
"depends_on": [
"task-004"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "4538f85d",
"validation": {
"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
},
"on_failure": {
"cleanup": null
},
"error_log": [],
"checkpoints": [
{
"step": 1,
"total": 2,
"description": "已审计 sidebar/document-content/CustomSideMenu 与 create/title/move route,确认第一批 tree command 已接入 envelope,但入口与部分树策略仍散落在前端组件层。",
"timestamp": "2026-04-17T08:32:00Z"
},
{
"step": 2,
"total": 2,
"description": "已新增共享 tree command client,并产出 design/tree-command-envelope-cutover-stage1-v1.md 固定第一批 cutover 边界与顺序。",
"timestamp": "2026-04-17T08:40:10Z"
}
],
"completed_at": "2026-04-17T08:40:10Z"
},
{
"id": "task-006",
"title": "执行 Stage C-1:为 Rust Web 正式实时树事件流补方案与接缝说明,明确 Convex substrate 与 Rust semantic owner 的订阅职责划分",
"status": "completed",
"priority": "P2",
"depends_on": [
"task-003",
"task-005"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "4538f85d",
"validation": {
"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
},
"on_failure": {
"cleanup": null
},
"error_log": [],
"checkpoints": [
{
"step": 1,
"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"
}
],
"completed_at": "2026-04-17T08:42:00Z"
},
{
"id": "task-007",
"title": "执行 Stage C-2:回写新的 harness 批次状态、阶段完成度与长期口径,明确哪些已进入稳定主链,哪些仍属于实验壳/后续阶段",
"status": "completed",
"priority": "P1",
"depends_on": [
"task-003",
"task-004",
"task-005",
"task-006"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "4538f85d",
"validation": {
"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",
"timeout_seconds": 120
},
"on_failure": {
"cleanup": null
},
"error_log": [],
"checkpoints": [
{
"step": 1,
"total": 1,
"description": "已回写 harness 状态与进度,并验证修复 dev server 的 Convex HTTP 代理后,3000 首页基线恢复:/auth 返回 200,/ 根路径稳定进入 /auth。",
"timestamp": "2026-04-17T08:56:30Z"
}
],
"completed_at": "2026-04-17T08:56:30Z"
},
{
"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 显式门控与首页 smoke3104 不可达时 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": {
"command": "true",
"timeout_seconds": 60
},
"on_failure": {
"cleanup": null
},
"error_log": [],
"checkpoints": [
{
"step": 1,
"total": 1,
"description": "已让 CustomSideMenu 的 pageReference 删除改走 shared tree command client。",
"timestamp": "2026-04-17T15:58:30Z"
}
],
"completed_at": "2026-04-17T15:58:30Z"
},
{
"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": {
"command": "true",
"timeout_seconds": 60
},
"on_failure": {
"cleanup": null
},
"error_log": [],
"checkpoints": [
{
"step": 1,
"total": 1,
"description": "已把 embed 收口为独立 documents.embed 命令,并补齐 TS/Rust 映射与测试。",
"timestamp": "2026-04-17T16:15:19Z"
}
],
"completed_at": "2026-04-17T16:15:19Z"
},
{
"id": "task-012",
"title": "执行 Stage P1-4:把 copy-tree 收口到 shared tree command client,移除 Sidebar 中文档复制的直调 route",
"status": "completed",
"priority": "P1",
"depends_on": [
"task-011"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "aa6ee384",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"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"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "aa6ee384",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"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"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "aa6ee384",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"on_failure": {
"cleanup": null
},
"error_log": [],
"checkpoints": [
{
"step": 1,
"total": 1,
"description": "已移除主路径 projection fallback/synthetic projection idsidebar/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"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "aa6ee384",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"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",
"priority": "P3",
"depends_on": [
"task-015"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "aa6ee384",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"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",
"priority": "P3",
"depends_on": [
"task-016"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "aa6ee384",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"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",
"priority": "P4",
"depends_on": [
"task-017"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "aa6ee384",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"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"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "aa6ee384",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"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",
"priority": "P0",
"depends_on": [
"task-019"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "aa6ee384",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"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"
},
{
"id": "task-021",
"title": "执行 TreeShell Phase A-1:产出共享 tree projection contract 文档,冻结 sidebar_tree/page_tree/file_tree 共用字段与差异字段",
"status": "completed",
"priority": "P0",
"depends_on": [
"task-020"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "f1c1bcf0",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"on_failure": {
"cleanup": null
},
"error_log": [],
"checkpoints": [
{
"step": 1,
"total": 1,
"description": "已产出共享 tree projection contract 文档,并冻结 sidebar_tree/page_tree/file_tree 的共享字段、row_id 与 resource_meta 口径。",
"timestamp": "2026-04-17T23:18:26Z"
}
],
"completed_at": "2026-04-17T23:18:26Z"
},
{
"id": "task-022",
"title": "执行 TreeShell Phase A-2:落地前后端共享 projection 类型,并冻结 file_tree 扩展字段与 capability/icon/resource 语义",
"status": "completed",
"priority": "P0",
"depends_on": [
"task-021"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "f1c1bcf0",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"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",
"priority": "P0",
"depends_on": [
"task-022"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "f1c1bcf0",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"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",
"priority": "P0",
"depends_on": [
"task-023"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "f1c1bcf0",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"on_failure": {
"cleanup": null
},
"error_log": [],
"checkpoints": [
{
"step": 1,
"total": 1,
"description": "已固定 projection truth 与本地 UI state 的边界,并锁定 expanded、selected、focus、dragging、drop target 不进入 projection。",
"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",
"priority": "P0",
"depends_on": [
"task-024"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "f1c1bcf0",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"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",
"priority": "P0",
"depends_on": [
"task-025"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "f1c1bcf0",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"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",
"title": "执行 TreeShell Phase B-2:让 Rust 直接输出 file_tree projection 的 document/index/asset 行语义,前端退出同类 synthetic row 真相",
"status": "completed",
"priority": "P0",
"depends_on": [
"task-026"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "f1c1bcf0",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"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",
"title": "执行 TreeShell Phase B-3:继续扩充 file_tree projection 到 book/pdf/index/iconHint/capabilities,收缩前端 adapter 责任",
"status": "completed",
"priority": "P1",
"depends_on": [
"task-027"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "f1c1bcf0",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"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",
"title": "执行 TreeShell Phase B-4:把树域 command 主协议切到 tree.*,保留 documents.* alias 与迁移护栏",
"status": "completed",
"priority": "P1",
"depends_on": [
"task-028"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "f1c1bcf0",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"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",
"title": "执行 TreeShell Phase B-5:补齐树域 route 的 trace/workspace/auth 边界与契约测试,防止主链继续依赖页面私有约定",
"status": "completed",
"priority": "P1",
"depends_on": [
"task-029"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "f1c1bcf0",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"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",
"title": "执行 TreeShell Phase B-6:收口 Next 树域 consumer,只保留 transport/compat 边界,退出前端主路径拼树时代",
"status": "completed",
"priority": "P1",
"depends_on": [
"task-030"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "f1c1bcf0",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"on_failure": {
"cleanup": null
},
"error_log": [],
"checkpoints": [
{
"step": 1,
"total": 1,
"description": "Next 树域主路径已收口为 transport/compateslint 通过且 buildDocumentTree 主路径检查通过。",
"timestamp": "2026-04-18T00:38:02Z"
}
],
"completed_at": "2026-04-18T00:38:02Z"
},
{
"id": "task-032",
"title": "执行 TreeShell Phase C-1:为 Rust Web 正式树域 UI 壳补 Leptos scaffold、loader/dispatcher/state 骨架与 route 接缝",
"status": "completed",
"priority": "P0",
"depends_on": [
"task-031"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "f1c1bcf0",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"on_failure": {
"cleanup": null
},
"error_log": [],
"checkpoints": [
{
"step": 1,
"total": 1,
"description": "mnote-web 已接入 Leptos tree shell scaffoldtree_shell 模块与 loader/dispatcher/state 骨架测试通过。",
"timestamp": "2026-04-18T00:38:02Z"
}
],
"completed_at": "2026-04-18T00:38:02Z"
},
{
"id": "task-033",
"title": "执行 TreeShell Phase C-2:补正式 page_tree renderer 与交互通路,打通 create/rename/move/navigate 到真实网页 smoke",
"status": "completed",
"priority": "P0",
"depends_on": [
"task-032"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "f1c1bcf0",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"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",
"title": "执行 TreeShell Phase C-3:补 selection/focus/keyboard/dragging 的本地 UI state 机理,明确不回写 projection truth",
"status": "completed",
"priority": "P0",
"depends_on": [
"task-033"
],
"attempts": 1,
"max_attempts": 3,
"started_at_commit": "f1c1bcf0",
"validation": {
"command": "true",
"timeout_seconds": 60
},
"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": {
"command": "true",
"timeout_seconds": 60
},
"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": {
"command": "true",
"timeout_seconds": 60
},
"on_failure": {
"cleanup": null
},
"error_log": [],
"checkpoints": [
{
"step": 1,
"total": 1,
"description": "已从 sidebar.tsx 主路径移除 iframe/postMessage 实验壳依赖,Sidebar 主树回到统一 surface。",
"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": {
"command": "true",
"timeout_seconds": 60
},
"on_failure": {
"cleanup": null
},
"error_log": [],
"checkpoints": [
{
"step": 1,
"total": 1,
"description": "已完成 Sidebar 主树默认切流与 fallback 护栏,task101 网页 smoke 通过。",
"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": {
"command": "true",
"timeout_seconds": 60
},
"on_failure": {
"cleanup": null
},
"error_log": [],
"checkpoints": [
{
"step": 1,
"total": 1,
"description": "已完成 page/filetree/picker 默认切流与高频回归,task102 与前端测试通过。",
"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": {
"command": "true",
"timeout_seconds": 60
},
"on_failure": {
"cleanup": null
},
"error_log": [],
"checkpoints": [
{
"step": 1,
"total": 1,
"description": "已补性能报告,记录首包、首次可交互、切页延迟、大树展开延迟与 fallback。",
"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": {
"command": "true",
"timeout_seconds": 60
},
"on_failure": {
"cleanup": null
},
"error_log": [],
"checkpoints": [
{
"step": 1,
"total": 1,
"description": "已统一 page/file/picker renderer surfacesidebar.tsx 不再直接耦合旧树组件名。",
"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": {
"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 主路径 fallbackSSR/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",
"timeout_seconds": 7200
},
"on_failure": {
"cleanup": null
},
"error_log": [],
"checkpoints": [
{
"step": 1,
"total": 1,
"description": "已落地 slash 菜单、heading 折叠、有限缩进、[[page]] / ((block)) 最小引用交互;cargo test -p mnote-web editor_interactions 与 pnpm test 通过。",
"timestamp": "2026-04-18T05:32:20Z"
}
],
"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/commentstask103 与 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 reportai_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 模板只作为体验 benchmarkmnote-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 模板仅作体验 benchmarkleptos-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": []
}
],
"session_count": 11,
"last_session": "2026-04-18T17:51:55Z"
}