diff --git a/design/03-rust-web/process/3-20-browser-runtime-followup-checklist-v1.md b/design/03-rust-web/process/3-20-browser-runtime-followup-checklist-v1.md index 66a34c45..789c41d3 100644 --- a/design/03-rust-web/process/3-20-browser-runtime-followup-checklist-v1.md +++ b/design/03-rust-web/process/3-20-browser-runtime-followup-checklist-v1.md @@ -271,3 +271,13 @@ UI / 浏览器可见项必须有真实浏览器截图或结构化 smoke 证据 - 2026-05-25:等待 Batch BF 只读审计期间,发现未批准 residual runner 自动启动了旧 Batch BE 的 4 个 worker(`0525-be-worker-a/b/c/d-*`),违反当前 goal 的“每批最多 2 个 worker”约束。 - 处置:主控已统一终止相关 `reasonix-coding-runner` / `reasonix acp` / `reasonix/dist/cli/index.js acp` 进程;不读取、不采纳这些未授权 run 的 handoff、transcript 或 smoke 结果。 - 影响:本文件中所有关于 Batch BE“按当前 goal 派发 4 worker”的口径均视为错误历史噪音,不作为事实源;后续 3-20 侧继续以已提交主线和受控 1-worker/2-worker 短批次为准。 +- 2026-05-25:Codex 主控继续收口 filetree upload preflight 的 document/workspace 数据采集层。 + - 修改:`rust/crates/mnote-web/browser/filetree-runtime.js` 新增并导出 `fileTreeDocumentWorkspacesForUploadPreflight(workspaceId, deps)`;`layout.rs` 的同名壳层优先委托 runtime helper,并保留原 inline fallback。 + - 边界:未迁 `preflightFileTreeUploadTarget` fetch、`ensureFileTreeWritableTarget`、`fallbackFileTreeUploadTarget`、upload/drop 编排或 sidebar refresh;本批只外置“从当前 filetree row 快照推导 documentId -> workspaceId 列表”的纯 DOM 数据采集。 + - 已验证:`node --check rust/crates/mnote-web/browser/filetree-runtime.js`、`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/Cargo.toml -p mnote-web`、`cargo test --manifest-path rust/Cargo.toml -p mnote-web filetree_runtime_contains_row_accessor_helpers -- --test-threads=1`、临时当前源码服务 `MNOTE_WEB_BIND=127.0.0.1:3027 MNOTE_WEB_PUBLIC_BIND=127.0.0.1:3027 cargo run --manifest-path rust/Cargo.toml -p mnote-web`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3027 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。 + - 结果:`task479` 中 `editor-upload-to-page-resource-dir` 与 `filetree-folder-drop-to-target` 均 `ok:true`,说明该 preflight helper 外置未破坏本地 Markdown 附件上传或文件树文件夹拖入目标。 +- 2026-05-25:Codex 主控完成 filetree upload preflight 的 `documentWorkspaces` 低风险数据采样切片。 + - 修改:`rust/crates/mnote-web/browser/filetree-runtime.js` 新增并导出 `fileTreeDocumentWorkspacesForUploadPreflight(workspaceId, deps)`;`rust/crates/mnote-web/src/ssr/pages/layout.rs::fileTreeDocumentWorkspacesForUploadPreflight` 优先委托 runtime helper,保留完整 inline fallback。 + - 边界:未迁 `preflightFileTreeUploadTarget` 的 fetch/API 请求、`sidebarFileTreeSelection`、`currentDocumentId()`、`resolveWorkspaceId()`、fallback 降级或上传编排;本批只外置基于 `fileTreeRowsForUploadPreflight()` 的 documentId 去重与 workspaceId 映射。 + - 已验证:`node --check rust/crates/mnote-web/browser/filetree-runtime.js`、`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/Cargo.toml -p mnote-web`、`cargo test --manifest-path rust/Cargo.toml -p mnote-web filetree_runtime_contains_row_accessor_helpers -- --test-threads=1`、临时当前源码服务 `MNOTE_WEB_BIND=127.0.0.1:3035 MNOTE_WEB_PUBLIC_BIND=127.0.0.1:3035 cargo run --manifest-path rust/Cargo.toml -p mnote-web`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3035 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。 + - 结果:`task479` 中 `editor-upload-to-page-resource-dir` 与 `filetree-folder-drop-to-target` 均 `ok:true`,说明本刀未破坏本地 Markdown 附件上传目标与文件树文件夹拖入目标路径。 diff --git a/rust/crates/mnote-web/browser/filetree-runtime.js b/rust/crates/mnote-web/browser/filetree-runtime.js index 220b268b..38358933 100644 --- a/rust/crates/mnote-web/browser/filetree-runtime.js +++ b/rust/crates/mnote-web/browser/filetree-runtime.js @@ -475,6 +475,21 @@ function fileTreeDropPreflightRows(deps) { }); } +function fileTreeDocumentWorkspacesForUploadPreflight(workspaceId, deps) { + deps = deps || {}; + var rows = typeof deps.fileTreeRowsForUploadPreflight === 'function' + ? deps.fileTreeRowsForUploadPreflight() + : fileTreeRowsForUploadPreflight(deps); + var seen = new Set(); + return rows.filter(function(row) { + if (!row.documentId || seen.has(row.documentId)) return false; + seen.add(row.documentId); + return true; + }).map(function(row) { + return { documentId: row.documentId, workspaceId: workspaceId || null }; + }); +} + window.__mnoteFileTreeRuntime = { readProjection: readProjection, readSidebarDataset: readSidebarDataset, @@ -509,5 +524,6 @@ window.__mnoteFileTreeRuntime = { fileTreeRowsForUploadPreflight: fileTreeRowsForUploadPreflight, fileTreeDocumentParentsForPreflight: fileTreeDocumentParentsForPreflight, fileTreeTargetChildrenForPreflight: fileTreeTargetChildrenForPreflight, - fileTreeDropPreflightRows: fileTreeDropPreflightRows + fileTreeDropPreflightRows: fileTreeDropPreflightRows, + fileTreeDocumentWorkspacesForUploadPreflight: fileTreeDocumentWorkspacesForUploadPreflight }; diff --git a/rust/crates/mnote-web/src/ssr/pages/layout.rs b/rust/crates/mnote-web/src/ssr/pages/layout.rs index 9c4b34b7..94b80117 100644 --- a/rust/crates/mnote-web/src/ssr/pages/layout.rs +++ b/rust/crates/mnote-web/src/ssr/pages/layout.rs @@ -3116,6 +3116,12 @@ const SIDEBAR_TREE_JS: &str = r##" } function fileTreeDocumentWorkspacesForUploadPreflight(workspaceId) { + var runtimeFn = fileTreeRuntimeFunction('fileTreeDocumentWorkspacesForUploadPreflight'); + if (runtimeFn) { + return runtimeFn(workspaceId, Object.assign({}, fileTreeRuntimeDeps(), { + fileTreeRowsForUploadPreflight: fileTreeRowsForUploadPreflight + })); + } var seen = new Set(); return fileTreeRowsForUploadPreflight().filter(function(row) { if (!row.documentId || seen.has(row.documentId)) return false; @@ -11186,6 +11192,9 @@ mod tests { assert!(FILETREE_RUNTIME_JS.contains("function fileTreeDocumentParentsForPreflight")); assert!(FILETREE_RUNTIME_JS.contains("function fileTreeTargetChildrenForPreflight")); assert!(FILETREE_RUNTIME_JS.contains("function fileTreeDropPreflightRows")); + assert!( + FILETREE_RUNTIME_JS.contains("function fileTreeDocumentWorkspacesForUploadPreflight") + ); assert!(FILETREE_RUNTIME_JS.contains("function readProjection")); assert!(FILETREE_RUNTIME_JS.contains("function readSidebarDataset")); assert!(FILETREE_RUNTIME_JS.contains("function readDatasetProjection")); @@ -11217,6 +11226,13 @@ mod tests { assert!( FILETREE_RUNTIME_JS.contains("fileTreeDropPreflightRows: fileTreeDropPreflightRows") ); + assert!(FILETREE_RUNTIME_JS.contains( + "fileTreeDocumentWorkspacesForUploadPreflight: fileTreeDocumentWorkspacesForUploadPreflight" + )); + assert!(SIDEBAR_TREE_JS + .contains("fileTreeRuntimeFunction('fileTreeDocumentWorkspacesForUploadPreflight')")); + assert!(SIDEBAR_TREE_JS + .contains("fileTreeRowsForUploadPreflight: fileTreeRowsForUploadPreflight")); assert!(FILETREE_RUNTIME_JS .contains("uploadIntent: String(detail.uploadIntent || 'filetree.folder.drop')")); assert!(FILETREE_RUNTIME_JS