Skip to content

feat(memory): 存量 worktree 分片迁移工具 — legacy 分片合并/删除 (#2379) - #2519

Open
KingSystemHaiGo wants to merge 12 commits into
makecindy:mainfrom
KingSystemHaiGo:fix/2379-legacy-shard-migration
Open

feat(memory): 存量 worktree 分片迁移工具 — legacy 分片合并/删除 (#2379)#2519
KingSystemHaiGo wants to merge 12 commits into
makecindy:mainfrom
KingSystemHaiGo:fix/2379-legacy-shard-migration

Conversation

@KingSystemHaiGo

Copy link
Copy Markdown
Contributor

这次改了什么

摘要

修复 #2379 问题一的 P0 第二阶段:存量 worktree 分片迁移#2399 已让新会话读写 canonical(主仓)分片,但 #2399 合入前产生的旧 worktree 独立分片(实测 105 个分片里 54 个 worktree 分片、38 个 dialogue 一次性目录)仍留在磁盘上不再被访问。本 PR 提供一次性迁移工具:把有内容的 legacy 分片合并进 canonical 分片,空分片直接删除,恢复「记忆写进读不到的地方」的最后一环。

改动:

  • 新增 packages/maker-core/src/memory/migrate.ts
    • planLegacyShardMigration(memoryRoot) — 纯只读扫描,产出迁移计划(emptyToDelete / mergeCandidates / skipped)
    • runLegacyShardMigration(plan, opts) — 幂等执行(可重复跑):
      • 空分片(无合法 <type>_<slug>.md)→ 直接删(零内容零风险,记忆系统改造:worktree 分片断裂 + 缺回合后复盘机制 #2379 正文)
      • 有内容分片 → 合并进 canonical 分片:canonical 不存在则 rename 整个目录(快路径,fts.db 相对名不变仍有效);已存在则逐文件合并(同名同内容跳过 / 同名不同内容 = 冲突不覆盖,源目录保留供人工处理 / 不同名复制)
      • 合并后重建目标 MEMORY.md(复用 storage.rebuildIndex,与运行时行为一致);FTS 交由下次 open 时 sanityCheck 自动 rebuild(文件是 source of truth,fts.ts 设计原则;maker-core 不依赖 better-sqlite3)
      • 可选 backupRoot:迁移前先把受影响分片复制备份
    • 识别 legacy 分片的依据:meta.json.absPathresolveMemoryScopeKey 归一化后,canonical 目录名 ≠ 当前目录名 → 真正的旧 worktree 分片
    • 不碰:SSH 分片(目录名 ssh- 前缀,记忆系统改造:worktree 分片断裂 + 缺回合后复盘机制 #2379 约束 3)、无 meta.json 的残留目录(不猜不删)
  • 新增 migrate.test.ts(11 个 unit 用例,fake resolver 不 spawn git):计划生成 / 空分片删除 / rename 快路径 + meta.absPath 更新 / 同名同内容跳过 / 同名不同内容冲突保留源目录 / 备份 / 幂等 / SSH 与孤儿目录跳过
  • 新增 migrate.git-integration.test.ts(2 个真实 git worktree 端到端用例,pnpm test:git-integration 执行):真实 resolver 全链路合并 + 幂等复扫
  • 新增 scripts/migrate-maker-memory.mjs CLI:默认 dry-run 只出计划,--apply 执行,--backup-dir 备份,--json 机器可读;遵循 node --import tsx 先例(同 browser-capability-benchmark)

变更类型

  • feat 新功能

范围

  • 关联 Issue / 需求:记忆系统改造:worktree 分片断裂 + 缺回合后复盘机制 #2379(P0 第二阶段:存量分片迁移;不关闭 issue——P0.5 存量清理与 P1+ 复盘另议)
  • 本 PR 包含:迁移核心逻辑 + 13 个测试 + CLI 工具
  • 明确不包含:
  • 用户可见变化:运行 CLI 后,旧 worktree 分片合并进主仓分片或删除;空分片清除;无冲突情况下所有记忆在新会话可达
  • 是否存在 breaking change:无

UI 变化

不涉及:纯 maker-core 工具模块 + CLI 脚本,无 UI。

  • 引用的设计规范:不涉及

怎么验证的

自动验证

pnpm --filter @cindy/maker-core exec vitest run src/memory/migrate.test.ts
结果:11/11 通过(计划生成 / 空删 / rename 快路径+meta 更新 / 同名同内容跳过 / 冲突保留源 / 备份 / 幂等 / SSH 与孤儿跳过)

pnpm --filter @cindy/maker-core exec vitest run src/memory/migrate.git-integration.test.ts
结果:2/2 通过(真实 git worktree:合并全链路 + 幂等复扫;30s 超时避开 Windows 建库慢)

pnpm --filter @cindy/maker-core lint(改动文件)
结果:0 错误

pnpm --filter @cindy/maker-core build(tsc --noEmit)
结果:改动文件 0 错误(仓库存量 error 全部位于 pi 测试文件,与本次无关,clean 基线同样存在)

CLI 手工冒烟(真实 git worktree + 分片布局):
  dry-run 正确识别 legacy 分片 → --apply 合并(project_b.md copied)→ 源目录删除、
  主仓分片含两个文件 + 重建 MEMORY.md、备份目录完整

手工验证

不涉及(运行期行为验证需宿主 app;迁移工具行为已由 unit + 真实 git 端到端覆盖)。

未执行的验证

  • 宿主 Desktop 上对真实用户数据执行一次迁移(本机 105 分片盘点的数据不在此环境;迁移是显式工具,用户按需运行,运行前有 dry-run + 建议 backup-dir)

风险

风险分类

  • 权限 / 安全 / 用户数据(迁移操作用户 memory 文件;设计约束:冲突不覆盖、可选备份、幂等可重跑、SSH/孤儿不碰)

影响与回滚

  • 影响范围:
    • 只影响显式运行 CLI 的分片目录;空分片删除零风险(无内容);有内容分片仅在「canonical 分片存在且同名不同内容」时保留源目录不覆盖
    • rename 快路径不改变 fts.db 内容(相对文件名不变);慢路径合并后 FTS 由下次 open 的 sanityCheck 自动重建
    • meta.json.absPath 在 rename 后更新为 canonical scope key(原值为旧 worktree 路径)
    • 跨平台:路径操作全部经 path.join/relative + fs 原生 API;Windows 盘符 sanitize 与 storage.ts 同一规则
  • 回滚 / 降级方式:迁移前指定 --backup-dir 可完整还原;无备份时,有冲突的分片源目录保留、无冲突分片删除后可用 git/磁盘恢复工具找回(删除前建议备份);无数据格式变更、无 migration、无协议变更

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名(git commit -s,见 DCO
  • UI 改动已在「UI 变化」注明引用的设计规范章节(不涉及 UI 则跳过)
  • 未提交凭证、令牌或授权文件
  • 已补充必要文档
  • 已确认测试结果或说明未执行原因

…ndy#2379)

buildMemoryScopeKey 对本地会话原样透传 workdir 绝对路径, git linked
worktree (如 .cindy-worktrees/<name>) 与主仓被拆成两个独立 Store,
worktree 会话 memory_search 恒 0 命中 (makecindy#2379 问题一)。

新增 async resolveMemoryScopeKey (memory/scope-resolver.ts) 作为所有
getStore 调用方的统一入口: 本地会话先做 worktree 归一化 —— linked
worktree 的 cwd 映射为「主仓根 + cwd 相对 worktree 根的子路径」
(保留按 cwd 隔离语义, 不做整仓合并, 语义收敛见 makecindy#2379 评论); 非 git
目录 / git 不可用 / 探测失败一律回落现有行为; SSH 复合键分支不变。

- 进程内缓存 (正/负结果 60s TTL, in-flight 去重): withStore 是每次
  memory 工具调用的热路径, 不能每次 spawn git
- .git 标记上溯预检: 非仓库目录直接短路, 不 spawn git (也避开
  Windows 子进程 CWD 锁临时目录导致 teardown EPERM)
- 探测用 git -C <dir> rev-parse, 相对输出按 -C 目录解析 (兼容旧 git)
- agent 启动路径仅在 memory 开启时解析, 关闭零探测开销
- manager.getStore() 归一化兜底, resetWorkdir/runReview/UI 旁路同语义
- buildMemoryScopeKey 同步契约不变 (scope-key.test.ts 不动)

验证: scope-resolver.test.ts 17 用例 (真实临时 git 仓库 + fake probe);
maker-core 2301 通过; lizi-mcps 490 通过; 根 pnpm test:unit 全绿。

Signed-off-by: KingSystemHaiGo <kingsystemhaigo@users.noreply.github.com>
`git clone --separate-git-dir` 的 checkout 其 --git-common-dir basename 恰好
也是 .git, 旧实现会把主仓根错误推导到 git 存储目录, 普通会话被静默映射到
无关 Store (Codex review on makecindy#2399)。

- 探测改为单次 rev-parse 同取 toplevel / git-dir / git-common-dir (每次
  解析只 spawn 一次 git)
- 仅当 gitdir ≠ common-dir (真 linked worktree) 才应用映射; 普通 clone /
  submodule / separate-git-dir 一律原样返回
- 新增 fake probe 用例 + 真实 `git clone --separate-git-dir` 端到端用例

Signed-off-by: KingSystemHaiGo <kingsystemhaigo@users.noreply.github.com>
…akecindy#2379)

Codex review on makecindy#2399 第二轮两条跟进:

- 主仓本身是 --separate-git-dir 布局时, common-dir 的 dirname 不是工作树,
  mainRoot 改为 `git worktree list --porcelain` 第一条记录 (git 保证主工作
  树排第一, 布局带 core.worktree 指针时取到真实主 checkout)。已知限制:
  clone --separate-git-dir 不写 core.worktree 时 git 自身也无法反推真实
  checkout (worktree list 把 gitdir 父目录报为主工作树), resolver 跟随
  git 的 canonical 答案并在代码注释中记录。
- 真实 Git 组合矩阵 (多 worktree / separate-git-dir / 主仓内 cwd) 迁出默认
  unit tier: 新增 scope-resolver.git-integration.test.ts 由
  `pnpm test:git-integration` 执行, unit 层只保留一条真实 Git smoke +
  fake probe 全量覆盖 (engineering-conventions §3.1)。maker-core 在
  test-workspaces.config.mjs 增加 git-integration tier 声明与 unit
  exclude, 契约测试同步更新。

Signed-off-by: KingSystemHaiGo <kingsystemhaigo@users.noreply.github.com>
…第二阶段)

makecindy#2399 合入前, worktree 会话的 memory 落到独立分片目录, 归一化生效后
不再被访问。本 PR 提供一次性迁移: 扫描 maker-memory 根下所有分片,
空分片直接删除, 有内容分片合并进 canonical(主仓)分片。

- migrate.ts: planLegacyShardMigration(纯只读扫描) + runLegacyShardMigration
  (幂等执行)。同名同内容跳过 / 同名不同内容 = 冲突不覆盖(保留源目录);
  SSH 分片与无 meta.json 目录不碰; 可选 backupRoot 迁移前备份
- migrate.test.ts: 11 个 unit 用例(fake resolver, 不 spawn git)
- migrate.git-integration.test.ts: 2 个真实 git worktree 端到端用例
- scripts/migrate-maker-memory.mjs: CLI(dry-run 默认 / --apply 执行),
  遵循 node --import tsx 先例

Signed-off-by: KingSystemHaiGo <kingsystemhaigo@users.noreply.github.com>
@KingSystemHaiGo
KingSystemHaiGo requested a review from a team as a code owner August 12, 2026 07:39
@greptile-apps

greptile-apps Bot commented Aug 12, 2026

Copy link
Copy Markdown

Greptile Summary

本 PR 将本地 Git worktree 的记忆作用域统一到 canonical 主仓路径,并提供存量 legacy 分片的扫描、合并、备份和清理工具。

  • Agent、MCP 与 manager 统一使用异步 worktree scope resolver
  • 新增 legacy 分片迁移计划与执行逻辑,以及 dry-run/apply CLI
  • 补充单元测试和真实 Git worktree 集成测试

Confidence Score: 4/5

当前仍不宜合并,因为迁移期间活动 legacy store 的记忆写入会在源目录被改名后失败。

rename-then-remove 避免了并发写入进入待删目录,却让仍持有原目录路径的常驻 store 对不存在的父目录执行 fs.writeFile;该写入没有目录重建或重试,因此会直接失败。

Files Needing Attention: packages/maker-core/src/memory/migrate.ts, packages/maker-core/src/memory/storage.ts

Important Files Changed

Filename Overview
packages/maker-core/src/memory/migrate.ts 新增 legacy 分片迁移的计划、合并和安全删除流程;rename-then-remove 会使仍在运行的 legacy store 写入原路径时失败。
packages/maker-core/src/memory/migrate.test.ts 覆盖分片识别、冲突、备份、幂等及多种 rename 前内容竞态,但未覆盖目录被 rename 后活动 store 的实际写入。
packages/maker-core/src/memory/scope-resolver.ts 新增本地 Git worktree 到 canonical 主仓作用域的解析和缓存逻辑。
packages/maker-core/src/memory/manager.ts getStore 在缓存和创建 store 前统一解析本地 canonical scope key。
scripts/migrate-maker-memory.mjs 新增迁移计划预览、显式 apply、备份目录及 JSON 输出 CLI。

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[扫描 legacy 分片] --> B{是否为空}
  B -->|是| C[复查内容]
  C --> D[rename 到 trash]
  D --> E[最终复查]
  E --> F[删除或恢复]
  B -->|否| G{canonical 是否存在}
  G -->|否| H[rename 为 canonical]
  G -->|是| I[逐文件合并]
  I --> J[冲突与内容复查]
  J --> K[rename 到 trash]
  K --> L[最终复查并删除或恢复]
Loading
Prompt To Fix All With AI
### Issue 1
packages/maker-core/src/memory/migrate.ts:307
**活动分片写入被中断**

如果存量会话在源分片被 rename 到 trash 后、迁移结束前写入记忆,常驻 store 仍会对原目录执行 `fs.writeFile`;由于该目录已不存在且写路径不会重新创建目录或重试,写入会以 ENOENT 失败。慢路径第 400 行的同类 rename 也存在相同窗口。

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (9): Last reviewed commit: "fix(memory): Windows 正斜杠 scope key 拼写统一 ..." | Re-trigger Greptile

Comment thread packages/maker-core/src/memory/migrate.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8617327a57

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/maker-core/src/memory/migrate.ts
…#2519)

- Greptile P1 (migrate.ts): 未识别 .md 文件 (不符合 <type>_<slug>.md 规则
  但仍含内容) 不再随源目录删除 — 检测到即保留源目录供人工处理
- Codex P1 (migrate.ts): 已归档/删除的 Cindy worktree 加静态路径推导
  (deriveCanonicalFromCindyWorktreePath, .cindy-worktrees/<name> 形态),
  resolver live 探测失败时不再把旧记录判为孤儿
- Greptile Summary: 空分片删除前重新校验 (扫描后新增分片文件 → 跳过删除
  并报告, 防过期快照删掉新写入数据)

新增 3 个 unit 用例覆盖 (14 total)。

Signed-off-by: KingSystemHaiGo <kingsystemhaigo@users.noreply.github.com>
@KingSystemHaiGo

Copy link
Copy Markdown
Contributor Author

@dash-s-cindy[bot] / Greptile Summary 第三条(扫描与执行竞态)已修复(commit 6f4edaa):

空分片删除前新增重新校验:countShardFiles() 复查目录——若扫描后新增了合法分片文件(并发写入/迟到写入),跳过删除并报告 dir gained N shard file(s) since scan (race), kept,绝不让过期快照删掉新写入的数据。新增 unit 用例覆盖。

Comment thread packages/maker-core/src/memory/migrate.ts Outdated
Comment thread packages/maker-core/src/memory/migrate.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6f4edaaa5a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/maker-core/src/memory/migrate.ts Outdated
…#2519)

- Greptile P1 (migrate.ts): 只有未识别 .md 的 legacy 分片不再按「空」删 —
  归入 mergeCandidates 走数据保全路径 (canonical 不存在 rename 快路径 /
  已存在则未识别文件保留源目录), 未指定备份也不会丢用户内容
- Greptile P1 (migrate.ts): 空分片删除改 rename-then-remove — 复查放到
  rename 之后只看待删临时目录, 压缩 countShardFiles→fs.rm 之间的竞态窗口;
  删除前同时检查新增分片文件与未识别 .md
- Codex P1 (migrate.ts): 静态推导同时认 .cindy-worktrees 与 .xdt-worktrees
  (品牌迁移前旧形态), 老版托管 worktree 归档后不再判孤儿

新增 2 个 unit 用例 (16 total)。

Signed-off-by: KingSystemHaiGo <kingsystemhaigo@users.noreply.github.com>
Comment thread packages/maker-core/src/memory/migrate.ts
rename-then-remove 的 rename 后复查只查 countShardFiles, 未识别 .md
(notes.md 等) 在首次复查后、rename 前写入时仍会被递归删除。最终复查
补 findUnrecognizedMdFiles, 任一命中即恢复原目录名并报告。

新增 unit 用例: 扫描后写入未识别 .md → 跳过删除并报告 (17 total)。

Signed-off-by: KingSystemHaiGo <kingsystemhaigo@users.noreply.github.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c6f87e30ff

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/maker-core/src/memory/migrate.ts Outdated
Comment thread packages/maker-core/src/memory/migrate.ts Outdated
@MagicLizi MagicLizi added the awaiting-discussion 等待维护者讨论(review-pr) label Aug 12, 2026
…y#2519)

- Codex P1 (migrate.ts): 慢路径删源前复查新增合法分片 — gainedValid =
  当前合法数 − mergeFilesInto 快照数, >0 即保留源目录并报告 (快照后新写入
  的 <type>_<slug>.md 既没被合并也不算未识别, 直接删会丢)
- Codex P1 (migrate.ts): deriveCanonicalFromCindyWorktreePath 改段解析,
  同时接受 / 与 \ 分隔符 — Desktop 存储把 Windows workingDir 归一化为
  正斜杠 (C:/repo/.cindy-worktrees/...), 只认 path.sep 会漏判成孤儿

新增 2 个 unit 用例 (19 total)。

Signed-off-by: KingSystemHaiGo <kingsystemhaigo@users.noreply.github.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b381b803fb

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/maker-core/src/memory/migrate.ts Outdated
Comment thread packages/maker-core/src/memory/migrate.ts
Comment thread packages/maker-core/src/memory/migrate.ts Outdated
… on makecindy#2519)

- Codex P1: SSH 分片判定从目录名前缀改为 meta.absPath 的 ssh: scope key
  前缀 — sanitizeWorkdir 允许本地路径 (如 /ssh/proj) 恰好产出 ssh- 开头的
  目录名, 前缀误判会把本地 legacy 分片跳过成孤儿
- Greptile P1: 未识别内容检查从 .md 扩展为一切非系统非分片文件 —
  notes.txt / data.yaml 等非 Markdown 遗留内容不再随源目录删除
- Greptile P1: 删源前对已合并分片做源/目标逐字节内容对比 (findChangedAfterMerge)
  — 存量会话在复制后更新已有记忆时数量复查检测不到, 内容对比兜底

新增 3 个 unit 用例 (22 total)。

Signed-off-by: KingSystemHaiGo <kingsystemhaigo@users.noreply.github.com>
Comment thread packages/maker-core/src/memory/migrate.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9472bf5fce

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/maker-core/src/memory/migrate.ts Outdated
…akecindy#2519)

- Codex P1: 同数替换 (删 A 建 B) 时数量不变, gainedValid 检测不到 —
  新增 diffShardFilenames 文件名集合对比 (快照 vs 当前), added/missing
  任一命中即保留源目录, 替代原计数法
- Greptile P1: 全部复查完成后 fs.rm 前仍有写入窗口 — 慢路径删除改
  rename-then-remove: rename 后对 trash 目录做最终复查 (未识别 + 集合
  对比), 命中即恢复原目录名, 压缩删除前窗口

新增 1 个 unit 用例 (23 total)。

Signed-off-by: KingSystemHaiGo <kingsystemhaigo@users.noreply.github.com>
Comment thread packages/maker-core/src/memory/migrate.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7eab97f139

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/maker-core/src/memory/migrate.ts Outdated
…#2519)

存量会话在 findChangedAfterMerge 之后、rename 之前更新同名记忆时,
trash 目录文件名集合不变但内容新 — rename 后最终复查只查未识别 + 集合,
会删掉包含新版本的 trash 目录, canonical 保留旧版本。

rename 后最终复查补 findChangedAfterMerge (trash vs target 逐字节对比),
任一命中即恢复原目录名并报告 'content appeared or changed before remove'。

新增 1 个 unit 用例 (24 total)。

Signed-off-by: KingSystemHaiGo <kingsystemhaigo@users.noreply.github.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d56cc03d2c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/maker-core/src/memory/scope-resolver.ts Outdated
…cindy#2519 第八轮)

Desktop 存正斜杠路径 (C:/repo), 但 resolver 内 path.normalize/join 在
Windows 上产反斜杠 (C:/repo)。两者 sanitize 到同一磁盘目录, 而
MakerMemoryManager 按 raw scope key 缓存 Store — 主 checkout 会话
(正斜杠 key) 与 worktree 会话 (反斜杠 key) 会开两个实例指向同一
SQLite/索引, 一侧写入后另一侧 MEMORY.md 缓存过期。

修复: canonicalizeLocalWorkdir 返回前 matchSeparatorStyle — 仅当输入是
Windows 盘符正斜杠形态 (C:/... Desktop 归一化拼写) 时输出转正斜杠;
POSIX 风格路径与反斜杠输入保持 path.join 默认行为。

新增 1 个 unit 用例 + 更新 1 个缓存用例期望 (win32 分支)。

Signed-off-by: KingSystemHaiGo <kingsystemhaigo@users.noreply.github.com>
// 无法进入待删目录 (与备份目录同层, 名字带后缀避免冲突)。
const trashName = `${path.basename(shard.dir)}.trash-${now().replace(/[:.]/g, '-')}`;
const trashDir = path.join(path.dirname(shard.dir), trashName);
await fs.rename(shard.dir, trashDir);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 活动分片写入被中断

如果存量会话在源分片被 rename 到 trash 后、迁移结束前写入记忆,常驻 store 仍会对原目录执行 fs.writeFile;由于该目录已不存在且写路径不会重新创建目录或重试,写入会以 ENOENT 失败。慢路径第 400 行的同类 rename 也存在相同窗口。

Context Used: 使用和PR描述相同的语言进行评论 (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/maker-core/src/memory/migrate.ts
Line: 307

Comment:
**活动分片写入被中断**

如果存量会话在源分片被 rename 到 trash 后、迁移结束前写入记忆,常驻 store 仍会对原目录执行 `fs.writeFile`;由于该目录已不存在且写路径不会重新创建目录或重试,写入会以 ENOENT 失败。慢路径第 400 行的同类 rename 也存在相同窗口。

**Context Used:** 使用和PR描述相同的语言进行评论 ([source](https://app.greptile.com/review/custom-context?memory=instruction-0))

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

@MagicLizi

Copy link
Copy Markdown
Contributor

维护者确认

本 PR 为 memory 存量 worktree 分片迁移新功能(2251 行,触及 maker-core 核心路径),触发产品确认门。

确认方式:请维护者直接在 PR 上 Approve;如需修改请 Request Changes,作者改完后重新 Approve 即放行。

讨论 issue:#2529

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-discussion 等待维护者讨论(review-pr)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants