Worktree files silently deleted by snapshot tracking — "file did not exist in snapshot, deleting" (58 events / ~15 incidents / 3 workspaces; strongest trigger: cancelling a session)
This report is informational only. No action is requested on any timeline. It exists so the team can see and know about a silent data-loss path, with as much forensic detail as I could gather, in case it helps improve the project.
Disclosure: written by an AI agent on the user's behalf and reviewed by the user. Desensitization: project roots replaced by <workspace> / <project-A> / <workspace-B>; file names masked to their first 2–3 characters plus extension (uniqueness within each table is preserved); one referenced third-party project name is replaced by <ref-proj>. Log excerpts otherwise verbatim.
1. Summary
While opencode was running multiple concurrent sessions on a workspace, four user documents in the worktree were silently deleted by opencode's own snapshot/tracking machinery, 3.4 seconds after the user cancelled a session's stream. The deletions are recorded verbatim in opencode.log and correlate second-for-second with the NTFS USN journal.
The retained opencode.log contains 58 real deletion events across ~15 incidents on 3 different workspaces over ~5 weeks (2026-06-28 → 2026-07-30). Full inventory in §5, trigger pattern in §6, source-code-level root-cause analysis in §7, snapshot-repo forensics in §8, raw evidence excerpts in §9.
2. Primary incident (2026-07-30, all times UTC)
Verbatim opencode.log excerpt (paths desensitized, names masked):
timestamp=2026-07-30T02:08:23.304Z level=INFO run=1aacb8fe message=cancel session.id=ses_04f79604affe1QL4SZxM55PDmm
timestamp=2026-07-30T02:08:26.617Z level=INFO run=1aacb8fe message=tracking hash=51d67741c0b2c6911f549464a8e640e559ffe66e cwd="<workspace>" git="<opencode-data>/snapshot/b4bd7128f83123cd9b96dfae937a5b5778845a6e"
timestamp=2026-07-30T02:08:26.681Z level=INFO run=1aacb8fe message="file did not exist in snapshot, deleting" file="<workspace>/Doc/设计/初始设***.md" hash=3d52279f2d52f55848553ed8b8f8c065121ec789
timestamp=2026-07-30T02:08:26.682Z level=INFO run=1aacb8fe message="file did not exist in snapshot, deleting" file="<workspace>/Doc/设计/执行手册/规则与***.md" hash=3d52279f2d52f55848553ed8b8f8c065121ec789
timestamp=2026-07-30T02:08:26.685Z level=INFO run=1aacb8fe message="file did not exist in snapshot, deleting" file="<workspace>/Doc/设计/模块设计与待执行计划/战斗系***.md" hash=3d52279f2d52f55848553ed8b8f8c065121ec789
timestamp=2026-07-30T02:08:26.686Z level=INFO run=1aacb8fe message="file did not exist in snapshot, deleting" file="<workspace>/Doc/设计/补充资料/初始设***Raw_V3.md" hash=3d52279f2d52f55848553ed8b8f8c065121ec789
NTFS USN journal, same second (reason 0x80000200: 文件删除 | 关闭), sequential USNs — a single batch operation:
Usn : 17852301200 文件名 : 初始设***.md 原因 : 0x80000200 时间戳 : 2026/7/30 10:08:26 (local, UTC+8)
Usn : 17852301312 文件名 : 规则与***.md 原因 : 0x80000200 时间戳 : 2026/7/30 10:08:26
Usn : 17852301408 文件名 : 战斗系***.md 原因 : 0x80000200 时间戳 : 2026/7/30 10:08:26
Usn : 17852301496 文件名 : 初始设***Raw_V3.md 原因 : 0x80000200 时间戳 : 2026/7/30 10:08:26
Corollary record: opencode's per-session diff tracking wrote <opencode-data>/storage/session_diff/ses_04f79604affe1QL4SZxM55PDmm.json at 2026/7/30 10:08:27 local — one second after the deletions.
3. Victim profile of the primary incident
All four files had been modified minutes before the deletion, by two different writers: a parallel opencode session (edit tool) and an external editor (VS Code with autoSave enabled). All four have non-ASCII (CJK) file names — significant for root cause RC1 (§7). Files in the same directories with ASCII names, or not touched for a long time, were not deleted.
4. Source analyzed
Root-cause analysis (§7) was performed on a fresh shallow clone of anomalyco/opencode, dev branch HEAD at analysis time. Installed build is desktop 1.18.6 (§11), so line numbers may differ slightly.
5. Full historical inventory (58 deletions, grouped by incident)
Every file did not exist in snapshot, deleting event in the retained log. Roots desensitized; names masked but unique within each table.
<project-A>
| # |
Timestamp (UTC) |
File |
| 1 |
2026-06-28T02:52:14.825Z |
<project-A>/.agent/steering/Tauri桌***.md |
| 2–4 |
2026-06-28T07:03:39.136–138Z |
<project-A>/project/<project-A>/.codebase-memory/.gitattributes, artifact.json, graph.db.zst |
| 5–7 |
2026-06-28T07:03:46.517–533Z |
(same 3 again) |
| 8–10 |
2026-06-28T07:03:50.850–852Z |
(same 3 again) |
| 11–14 |
2026-06-28T08:56:26.518–521Z |
<project-A>/.agent/steering/CLI子***.md, 联网搜***.md, 多代理***.md, <project-A>/.agent/当前文***.md |
| 15–17 |
2026-06-28T11:15:40.924–930Z |
.../_internal/src/adapters/opencode/con***.toml, pri***.toml, .../adapters/siliconflow/con***.toml |
| 18 |
2026-06-28T12:18:38.227Z |
<project-A>/scripts/opencode_go***.py |
| 19–34 |
2026-06-28T13:44:56.472–761Z |
.../gui/src/types/ind***.ts, .../src/mod***.py, .../gui/src/locales/zh-***.ts, .../adapters/siliconflow/pri***_formula.toml, .../common/Emp***.ts, Mod***.ts, Sor***.ts, .../pages/Cha***.ts, <project-A>/.agent/specs/识别代***.md, .../gui/src/App***.css, .../_internal/src/mod***.py, .../layout/Sid***.ts |
| 35–39 |
2026-06-28T13:44:57.705–708Z |
.../_internal/config/con***.example.toml, .../adapters/opencode/pri***_formula.toml, .../adapters/siliconflow/pri***_formula.toml, .../backend/config/con***.example.toml, con***.toml |
| 40 |
2026-06-28T13:44:57.993Z |
<project-A>/scripts/opencode_go***.py (again) |
| 41 |
2026-07-02T18:10:37.370Z |
<project-A>/.agent/steering/人机交***.md |
| 42 |
2026-07-02T19:30:55.570Z |
<project-A>/.agent/steering/人机交***.md (again) |
| 43–44 |
2026-07-03T19:24:33.719–721Z |
<project-A>/.agent/skills状态/boa***.json, .../pages/Pol***.ts |
| 45 |
2026-07-07T04:06:41.231Z |
<project-A>/Doc/记忆和上下文/情景记***_2026-07-07.md |
| 46–48 |
2026-07-07T11:20:58.801–803Z |
.../pages/HomePage/ind***.ts, .../ModelMappingPage/use***.ts, .../src/ser***.py |
| 49–51 |
2026-07-11T17:47:40.385–457Z |
<project-A>/Doc/记忆和上下文/情景记***_2026-07-12.md, <project-A>/Doc/设计/功能补***_GUI.md, 功能补***_渠道部署.md, 功能补***_管道查询激活.md |
| 52 |
2026-07-13T16:20:18.295Z |
<project-A>/Doc/Agent提示词/子代理***.md |
<workspace-B>
| # |
Timestamp (UTC) |
File |
| 53–54 |
2026-07-05T02:48:42.288–289Z |
<workspace-B>/Tool/sync_***.json, sync_***.txt |
| 55 |
2026-07-13T02:02:15.645Z |
<workspace-B>/Doc/深度研究/Codex与***_2026-07-13.md |
<workspace>
| # |
Timestamp (UTC) |
File |
| 56–57 |
2026-07-19T11:57:14.604Z, 12:00:29.013Z |
<workspace>/Doc/参考项目/<ref-proj> AI系统***.md (twice) |
| 58 |
2026-07-26T10:15:40.821Z |
<workspace>/Tool/.Agent/Skills状态/fake-identity/data/fet***.txt |
| 59–62* |
2026-07-30T02:08:26.681–686Z |
the four files of the primary incident (§2) |
(Raw pattern-match count includes 2 false positives caused by the investigator's own Select-String commands matching the phrase — excluded from all counts.)
6. Trigger pattern (prediction logic)
- Cancelling a session's stream is the highest-risk moment. The three largest incidents fired 0.7–7 s after a
cancel (verbatim excerpts in §9): 06-28 08:56 (0.8 s), 06-28 13:44 double-cancel (3.1 s, ~17 files), 07-30 (3.4 s).
- Write/tracking race. On 07-19 the log shows opencode writing a file (
touching file) and deleting it 9.3 s later in the next tracking pass. Periodic tracking and instance-startup tracking also delete without any cancel (06-28 07:03: init → deletion ~15 s later).
- Victim profile: every deleted file was recently modified, mid-write, or open in an external editor. Nothing untouched was ever deleted.
- Variant: on 07-26 the same mechanism logged
reverting file= instead of deleting — the same reconciliation path can also revert content.
7. Likely root causes (source analysis)
From packages/opencode/src/snapshot/index.ts and packages/opencode/src/session/revert.ts (dev HEAD).
RC1 — Non-ASCII file names are always misjudged "not in snapshot" and are deleted instead of reverted/kept (explains every CJK-named victim).
In revert(), the snapshot-existence checks run git ls-tree via the core arg set, which does not include -c core.quotepath=false (single-file check at line 431; batched check at line 466), while every sibling function (add, patch, diff, ignore) uses the quote arg set, which does include it. With git's default core.quotepath=true, ls-tree output octal-escapes non-ASCII path components (e.g. "Doc/\346\267\261\..."), but the comparison targets (op.rel) are raw UTF-8. have.has(op.rel) (lines 485–492) and the single-file tree.text.trim() truthiness check (line 434) therefore never match for CJK-named files, so control falls through to remove(op.file) (lines 441–442 and 516–517).
In the primary incident all four victims share one patch hash and non-clashing paths, so they took the batched path, where the batched ls-tree is the only existence check and checkout is only attempted for files in have. With have empty for all CJK rels, no checkout was even attempted — all four were deleted outright. This also explains why ASCII-named files in the same directories survived.
RC2 — Patch scope is worktree-global, so reverting one session sweeps up other writers' changes (explains ASCII-named mass victims).
patch()/diff() are computed over the whole worktree (-- .), and SessionRevert.revert (session/revert.ts line 72) reverts every patch part after the revert point regardless of which process made those changes. In the primary incident the four files had just been modified by a different session and by an external editor; cancelling session-B reverted a window containing those writes. Files created inside a reverted window are absent from the patch tree by design and are deleted — which matches the large ASCII-named batches (e.g. 06-28 13:44, ~17 files).
RC3 — Policy-excluded files are deletion candidates (explains large-binary victims).
Files larger than 2 MiB are never staged into the snapshot (limit, lines 24 and 277–295), so any revert judges them "not in snapshot" and deletes them (e.g. .codebase-memory/graph.db.zst, deleted three times in a row on 06-28 07:03). Newly-gitignored files are explicitly dropped from the snapshot index (lines 267–272) and likewise become deletion candidates. There is no keep-list for policy exclusions.
Trigger path: stream cancel → aborted-message handling → SessionRevert.revert → Snapshot.revert → RC1/RC2/RC3 fire.
8. Snapshot repo forensics
The snapshot bare repo for the primary workspace (<opencode-data>/snapshot/b4bd7128f83123cd9b96dfae937a5b5778845a6e/788320baec536c80a99a371151efb1a52067ff53), inspected read-only:
git for-each-ref → empty; packed-refs contains only the header # pack-refs with: peeled fully-peeled sorted.
git log → fatal: your current branch 'master' does not have any commits yet. The repo holds only dangling objects (trees/blobs, no refs).
git cat-file -t 51d67741c0b2c6911f549464a8e640e559ffe66e (the tracking hash= in the primary incident) → tree.
git show --stat 3d52279f2d52f55848553ed8b8f8c065121ec789 (the hash= attached to the four deletion lines) → a tree whose root is .codebase-memory/, .gitignore, Doc/, README.md, Tool/.
- Descending that tree: its
Doc/设计/ subtree does contain 初始设***.md — the path the deletion message claims "did not exist in snapshot" is in fact present in the referenced tree. This corroborates RC1: the judgment failed at the output-comparison stage (octal-escaped vs raw UTF-8), not because the path was absent.
9. Raw trigger-context excerpts (verbatim opencode.log)
06-28 08:56 incident (<project-A>):
08:56:25.731Z message=cancel session.id=ses_0f2927d84ffe036gR7ipnQq9zn
08:56:26.433Z message=tracking hash=e3041c52505c08ce5a7b4b97f1b40e55257430ad cwd="<project-A>" git="<opencode-data>/snapshot/..."
08:56:26.518Z message="file did not exist in snapshot, deleting" file="<project-A>/.agent/steering/CLI子***.md"
06-28 13:44 mass incident (<project-A>):
13:44:47.494Z message="touching file" file="<project-A>/.agent/steering/git守***.md"
13:44:48.469Z message="touching file" file="<project-A>/.agent/steering/Harn***.md"
13:44:49.021Z message=cancel session.id=ses_0f186f3d0ffeP1dE7b5WTGO41L
13:44:49.022Z level=ERROR message=process ... error=Aborted stack="AbortError: Aborted ..."
13:44:53.336Z message=cancel session.id=ses_0f202f243ffe7bzTVU5Jnf0KBB
13:44:53.337Z level=ERROR message=process ... error=Aborted stack="AbortError: Aborted ..."
13:44:56.472Z message="file did not exist in snapshot, deleting" file=".../gui/src/types/ind***.ts" (→ ~17 files within 1.5 s)
06-28 07:03 startup incident (<project-A>):
07:03:23.809Z message="global event connected"
07:03:24.231Z message=bootstrapping directory="<workspace-B>"
07:03:28.877Z message=init count=1
07:03:39.036Z message=tracking hash=a2aef99224ee8e49c904462d1bc05e11c551f060 cwd="<project-A>" git="<opencode-data>/snapshot/..."
07:03:39.136Z message="file did not exist in snapshot, deleting" file="<project-A>/project/<project-A>/.codebase-memory/.gitattributes"
07-19 write-then-delete race (<workspace>):
11:57:05.334Z message=formatting file="<workspace>/Doc/参考项目/<ref-proj> AI系统***.md"
11:57:05.334Z message="touching file" file="<workspace>/Doc/参考项目/<ref-proj> AI系统***.md"
11:57:05.868Z message=tracking hash=dae6e2662312cecbd664b3311831f7d93d86f36d cwd="<workspace>" git="<opencode-data>/snapshot/..."
11:57:14.604Z message="file did not exist in snapshot, deleting" file="<workspace>/Doc/参考项目/<ref-proj> AI系统***.md"
07-26 revert variant (<workspace>):
10:15:40.672Z message=reverting file="<workspace>/Tool/.Agent/Skills产物/fake-identity/data/fet***.txt" hash=d2af6fda...
10. Environment
Windows 11 Pro for Workstations, 25H2, build 26200 (GBK locale — relevant to RC1, since core.quotepath octal-escaping hits all CJK-named files). OpenCode desktop 1.18.6 (Electron installer; session DB reports "version": "local"). Multiple concurrent sessions (TUI via Windows Terminal + PowerShell 5.1, and desktop app WebView2). VS Code with files.autoSave enabled was open on some of the same files (ruled out as the deleter via USN + log correlation; it separately overwrote one recovered file from a stale editor buffer 35 minutes later — a distinct, user-side mechanism).
Plugins: none third-party (opencode.json has no plugin key; package.json lists only SDK dependency "@opencode-ai/plugin": "1.4.6").
11. Steps to reproduce
Probabilistic (race-dependent); matches all 58 observed events:
- Run multiple concurrent opencode sessions on one workspace.
- Have files modified very recently — ideally some with non-ASCII names (CJK) — by another session's edit tool or an external editor with autoSave.
- Do one of: a. cancel a session's stream (strongest trigger), b. start the instance while such files are mid-write, c. wait for a periodic
tracking pass during active writes.
- Within ~1–7 seconds, check
git status for unexpected deletions and opencode.log for file did not exist in snapshot, deleting.
Expected: reconciliation never deletes a worktree file that exists on disk; a file that exists in the patch tree is restored, a file that cannot be read is skipped, never deleted.
Actual: files are deleted in a single batch, seconds after the trigger, with only an INFO-level log line.
12. Screenshot and/or share link
No screenshot; verbatim opencode.log excerpts with timestamps are quoted in §2 and §9, USN delete records in §2, and the source-level defect is cited with file/line in §7. Raw artifacts available on request (§13).
End of report. No action requested — sharing for visibility only.
Worktree files silently deleted by snapshot tracking — "file did not exist in snapshot, deleting" (58 events / ~15 incidents / 3 workspaces; strongest trigger: cancelling a session)
1. Summary
While opencode was running multiple concurrent sessions on a workspace, four user documents in the worktree were silently deleted by opencode's own snapshot/tracking machinery, 3.4 seconds after the user cancelled a session's stream. The deletions are recorded verbatim in
opencode.logand correlate second-for-second with the NTFS USN journal.The retained
opencode.logcontains 58 real deletion events across ~15 incidents on 3 different workspaces over ~5 weeks (2026-06-28 → 2026-07-30). Full inventory in §5, trigger pattern in §6, source-code-level root-cause analysis in §7, snapshot-repo forensics in §8, raw evidence excerpts in §9.2. Primary incident (2026-07-30, all times UTC)
Verbatim
opencode.logexcerpt (paths desensitized, names masked):NTFS USN journal, same second (reason
0x80000200: 文件删除 | 关闭), sequential USNs — a single batch operation:Corollary record: opencode's per-session diff tracking wrote
<opencode-data>/storage/session_diff/ses_04f79604affe1QL4SZxM55PDmm.jsonat2026/7/30 10:08:27local — one second after the deletions.3. Victim profile of the primary incident
All four files had been modified minutes before the deletion, by two different writers: a parallel opencode session (edit tool) and an external editor (VS Code with autoSave enabled). All four have non-ASCII (CJK) file names — significant for root cause RC1 (§7). Files in the same directories with ASCII names, or not touched for a long time, were not deleted.
4. Source analyzed
Root-cause analysis (§7) was performed on a fresh shallow clone of
anomalyco/opencode,devbranch HEAD at analysis time. Installed build is desktop 1.18.6 (§11), so line numbers may differ slightly.5. Full historical inventory (58 deletions, grouped by incident)
Every
file did not exist in snapshot, deletingevent in the retained log. Roots desensitized; names masked but unique within each table.<project-A><project-A>/.agent/steering/Tauri桌***.md<project-A>/project/<project-A>/.codebase-memory/.gitattributes,artifact.json,graph.db.zst<project-A>/.agent/steering/CLI子***.md,联网搜***.md,多代理***.md,<project-A>/.agent/当前文***.md.../_internal/src/adapters/opencode/con***.toml,pri***.toml,.../adapters/siliconflow/con***.toml<project-A>/scripts/opencode_go***.py.../gui/src/types/ind***.ts,.../src/mod***.py,.../gui/src/locales/zh-***.ts,.../adapters/siliconflow/pri***_formula.toml,.../common/Emp***.ts,Mod***.ts,Sor***.ts,.../pages/Cha***.ts,<project-A>/.agent/specs/识别代***.md,.../gui/src/App***.css,.../_internal/src/mod***.py,.../layout/Sid***.ts.../_internal/config/con***.example.toml,.../adapters/opencode/pri***_formula.toml,.../adapters/siliconflow/pri***_formula.toml,.../backend/config/con***.example.toml,con***.toml<project-A>/scripts/opencode_go***.py(again)<project-A>/.agent/steering/人机交***.md<project-A>/.agent/steering/人机交***.md(again)<project-A>/.agent/skills状态/boa***.json,.../pages/Pol***.ts<project-A>/Doc/记忆和上下文/情景记***_2026-07-07.md.../pages/HomePage/ind***.ts,.../ModelMappingPage/use***.ts,.../src/ser***.py<project-A>/Doc/记忆和上下文/情景记***_2026-07-12.md,<project-A>/Doc/设计/功能补***_GUI.md,功能补***_渠道部署.md,功能补***_管道查询激活.md<project-A>/Doc/Agent提示词/子代理***.md<workspace-B><workspace-B>/Tool/sync_***.json,sync_***.txt<workspace-B>/Doc/深度研究/Codex与***_2026-07-13.md<workspace><workspace>/Doc/参考项目/<ref-proj> AI系统***.md(twice)<workspace>/Tool/.Agent/Skills状态/fake-identity/data/fet***.txt(Raw pattern-match count includes 2 false positives caused by the investigator's own
Select-Stringcommands matching the phrase — excluded from all counts.)6. Trigger pattern (prediction logic)
cancel(verbatim excerpts in §9): 06-28 08:56 (0.8 s), 06-28 13:44 double-cancel (3.1 s, ~17 files), 07-30 (3.4 s).touching file) and deleting it 9.3 s later in the nexttrackingpass. Periodictrackingand instance-startuptrackingalso delete without any cancel (06-28 07:03:init→ deletion ~15 s later).reverting file=instead of deleting — the same reconciliation path can also revert content.7. Likely root causes (source analysis)
From
packages/opencode/src/snapshot/index.tsandpackages/opencode/src/session/revert.ts(devHEAD).RC1 — Non-ASCII file names are always misjudged "not in snapshot" and are deleted instead of reverted/kept (explains every CJK-named victim).
In
revert(), the snapshot-existence checks rungit ls-treevia thecorearg set, which does not include-c core.quotepath=false(single-file check at line 431; batched check at line 466), while every sibling function (add,patch,diff,ignore) uses thequotearg set, which does include it. With git's defaultcore.quotepath=true,ls-treeoutput octal-escapes non-ASCII path components (e.g."Doc/\346\267\261\..."), but the comparison targets (op.rel) are raw UTF-8.have.has(op.rel)(lines 485–492) and the single-filetree.text.trim()truthiness check (line 434) therefore never match for CJK-named files, so control falls through toremove(op.file)(lines 441–442 and 516–517).In the primary incident all four victims share one patch hash and non-clashing paths, so they took the batched path, where the batched
ls-treeis the only existence check and checkout is only attempted for files inhave. Withhaveempty for all CJK rels, no checkout was even attempted — all four were deleted outright. This also explains why ASCII-named files in the same directories survived.RC2 — Patch scope is worktree-global, so reverting one session sweeps up other writers' changes (explains ASCII-named mass victims).
patch()/diff()are computed over the whole worktree (-- .), andSessionRevert.revert(session/revert.tsline 72) reverts everypatchpart after the revert point regardless of which process made those changes. In the primary incident the four files had just been modified by a different session and by an external editor; cancelling session-B reverted a window containing those writes. Files created inside a reverted window are absent from the patch tree by design and are deleted — which matches the large ASCII-named batches (e.g. 06-28 13:44, ~17 files).RC3 — Policy-excluded files are deletion candidates (explains large-binary victims).
Files larger than 2 MiB are never staged into the snapshot (
limit, lines 24 and 277–295), so any revert judges them "not in snapshot" and deletes them (e.g..codebase-memory/graph.db.zst, deleted three times in a row on 06-28 07:03). Newly-gitignored files are explicitly dropped from the snapshot index (lines 267–272) and likewise become deletion candidates. There is no keep-list for policy exclusions.Trigger path: stream
cancel→ aborted-message handling →SessionRevert.revert→Snapshot.revert→ RC1/RC2/RC3 fire.8. Snapshot repo forensics
The snapshot bare repo for the primary workspace (
<opencode-data>/snapshot/b4bd7128f83123cd9b96dfae937a5b5778845a6e/788320baec536c80a99a371151efb1a52067ff53), inspected read-only:git for-each-ref→ empty;packed-refscontains only the header# pack-refs with: peeled fully-peeled sorted.git log→fatal: your current branch 'master' does not have any commits yet. The repo holds only dangling objects (trees/blobs, no refs).git cat-file -t 51d67741c0b2c6911f549464a8e640e559ffe66e(thetracking hash=in the primary incident) →tree.git show --stat 3d52279f2d52f55848553ed8b8f8c065121ec789(thehash=attached to the four deletion lines) → a tree whose root is.codebase-memory/,.gitignore,Doc/,README.md,Tool/.Doc/设计/subtree does contain初始设***.md— the path the deletion message claims "did not exist in snapshot" is in fact present in the referenced tree. This corroborates RC1: the judgment failed at the output-comparison stage (octal-escaped vs raw UTF-8), not because the path was absent.9. Raw trigger-context excerpts (verbatim
opencode.log)06-28 08:56 incident (
<project-A>):06-28 13:44 mass incident (
<project-A>):06-28 07:03 startup incident (
<project-A>):07-19 write-then-delete race (
<workspace>):07-26 revert variant (
<workspace>):10. Environment
Windows 11 Pro for Workstations, 25H2, build 26200 (GBK locale — relevant to RC1, since
core.quotepathoctal-escaping hits all CJK-named files). OpenCode desktop 1.18.6 (Electron installer; session DB reports"version": "local"). Multiple concurrent sessions (TUI via Windows Terminal + PowerShell 5.1, and desktop app WebView2). VS Code withfiles.autoSaveenabled was open on some of the same files (ruled out as the deleter via USN + log correlation; it separately overwrote one recovered file from a stale editor buffer 35 minutes later — a distinct, user-side mechanism).Plugins: none third-party (
opencode.jsonhas nopluginkey;package.jsonlists only SDK dependency"@opencode-ai/plugin": "1.4.6").11. Steps to reproduce
Probabilistic (race-dependent); matches all 58 observed events:
trackingpass during active writes.git statusfor unexpected deletions andopencode.logforfile did not exist in snapshot, deleting.Expected: reconciliation never deletes a worktree file that exists on disk; a file that exists in the patch tree is restored, a file that cannot be read is skipped, never deleted.
Actual: files are deleted in a single batch, seconds after the trigger, with only an INFO-level log line.
12. Screenshot and/or share link
No screenshot; verbatim
opencode.logexcerpts with timestamps are quoted in §2 and §9, USN delete records in §2, and the source-level defect is cited with file/line in §7. Raw artifacts available on request (§13).End of report. No action requested — sharing for visibility only.