Skip to content

Commit 1c1bc49

Browse files
authored
docs(windows): WSL troubleshooting guide; point UNSUPPORTED_PLATFORM at it (#152)
docs(windows): WSL troubleshooting guide; point UNSUPPORTED_PLATFORM at it
2 parents a3b3df4 + 3adc7b6 commit 1c1bc49

8 files changed

Lines changed: 105 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,21 @@ Notable changes to claude-obsidian are recorded here using
55
[Semantic Versioning](https://semver.org/). Git history retains the detailed
66
implementation record for older releases.
77

8+
## [Unreleased]
9+
10+
### Added
11+
12+
- `docs/windows-wsl.md`: platform support matrix and WSL troubleshooting for
13+
native Windows users, covering the virtualization-conflict hang class
14+
(`wsl --status` hanging after install), approval-hash environment binding,
15+
and filesystem identity requirements. Linked from the README, install
16+
guide, compound vault guide, and the wiki skill's transaction reference.
17+
18+
### Changed
19+
20+
- The `UNSUPPORTED_PLATFORM` refusal message now points to
21+
`docs/windows-wsl.md` for users whose WSL setup is itself misbehaving.
22+
823
## [2.1.0] - 2026-07-31
924

1025
Native Windows compatibility.

README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
<a href="#from-source-to-living-knowledge">See the workflow</a> ·
2121
<a href="#quick-start">Quick start</a> ·
2222
<a href="#15-skills-one-system">Explore the skills</a> ·
23-
<a href="docs/install-guide.md">Installation guide</a>
23+
<a href="docs/install-guide.md">Installation guide</a> ·
24+
<a href="docs/windows-wsl.md">Windows &amp; WSL</a>
2425
</p>
2526

2627
claude-obsidian is a local-first knowledge system for Claude Code and compatible
@@ -349,11 +350,12 @@ CI exercises Linux and macOS, plus a native-Windows smoke job for the portable
349350
surface. On native Windows (including Git Bash), read-only inspection and
350351
dry-run commands work; vault writes require WSL and fail closed with an
351352
`UNSUPPORTED_PLATFORM` error otherwise. Approval hashes bind to the reviewing
352-
environment's filesystem identity, so run the dry-run review inside WSL when
353-
the apply will happen there — a natively produced `approved_plan_sha256`
354-
cannot be replayed from WSL. The bash setup scripts and shell test suites
355-
remain POSIX-only. Optional tools such as Obsidian CLI, Ollama, and defuddle
356-
are capability-detected and affect only their dependent workflow.
353+
environment, so review inside WSL when the apply will happen there. Platform
354+
details, the support matrix, and WSL troubleshooting (including hangs from
355+
virtualization conflicts) live in the
356+
[Windows and WSL guide](docs/windows-wsl.md). The bash setup scripts and shell
357+
test suites remain POSIX-only. Optional tools such as Obsidian CLI, Ollama,
358+
and defuddle are capability-detected and affect only their dependent workflow.
357359

358360
## Development and release
359361

claude_obsidian/transaction.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1388,7 +1388,8 @@ def _require_lock_dirfd_support() -> None:
13881388
_UNSUPPORTED_PLATFORM_MESSAGE = (
13891389
"vault writes require directory-descriptor confinement (WSL/Linux or "
13901390
"supported macOS); on native Windows run this command inside WSL — "
1391-
"read-only inspection and dry-runs work natively"
1391+
"read-only inspection and dry-runs work natively; if WSL itself "
1392+
"misbehaves, see docs/windows-wsl.md"
13921393
)
13931394

13941395

docs/compound-vault-guide.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ require WSL/Linux or supported macOS; native Windows and Git Bash are not
7676
supported mutation hosts and are refused with `UNSUPPORTED_PLATFORM` before
7777
any side effect. Read-only inspection and dry-runs run natively on Windows
7878
using point-in-time lstat validation (symlink and junction rejection) instead
79-
of descriptor pinning.
79+
of descriptor pinning. Platform specifics and WSL troubleshooting live in the
80+
[Windows and WSL guide](windows-wsl.md).
8081

8182
Raw source bytes can be supplied through hash-checked binary `content_file`
8283
writes, but their destination mode is create-only. Address allocation, page

docs/install-guide.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ for development, but a normal user vault should be a separate directory.
1515
- Obsidian when you want its visual editor
1616
- Bash for installer and optional legacy-extension scripts
1717
- Git only for source development, release builds, or explicit checkpoints
18+
- On Windows: WSL for vault writes; native Windows supports read-only
19+
inspection and dry-runs — see the [Windows and WSL guide](windows-wsl.md)
1820

1921
## Claude Code marketplace
2022

@@ -258,5 +260,8 @@ User notes, sources, ledgers, and Obsidian settings remain untouched.
258260
| Transaction conflict / exit 75 | Another operation is active or a target changed; reread, rebuild, and inspect a new bundle. |
259261
| Obsidian CLI is unavailable | Use filesystem reads; start/update Obsidian before retrying CLI transport. |
260262
| Capture adapter is not implemented | Inspect `capture adapters`; configure a separate runner only with explicit consent. |
263+
| Writes refused with `UNSUPPORTED_PLATFORM` on Windows | Vault mutation requires WSL; see the [Windows and WSL guide](windows-wsl.md). |
264+
| WSL installed but `wsl --status` hangs | Virtualization conflict class; work through the checklist in the [Windows and WSL guide](windows-wsl.md#wsl-troubleshooting). |
265+
| Native dry-run approval fails in WSL with `PLAN_CHANGED` | Approval hashes bind the reviewing environment; redo the dry-run inside WSL ([details](windows-wsl.md#wsl-troubleshooting)). |
261266

262267
Run `make test` in the product repository when developing or packaging changes.

docs/windows-wsl.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Windows and WSL guide
2+
3+
claude-obsidian supports native Windows as a read-only platform and WSL as the
4+
full-capability platform. This guide covers what works where, why the boundary
5+
exists, and how to unstick WSL when it misbehaves.
6+
7+
## Platform support
8+
9+
| Capability | WSL / Linux / macOS | Native Windows (incl. Git Bash) |
10+
|---|---|---|
11+
| Inspection, dry-run previews, retrieval | Yes | Yes |
12+
| Vault writes (`transaction apply`, `init`, `adopt`, `migrate`, `capture apply`, `mode set`) | Yes | No — refused with `UNSUPPORTED_PLATFORM` |
13+
| Capture queue commands (including read-only `capture queue list`) | Yes | No — currently refused; tracked in [#151](https://github.com/AgriciDaniel/claude-obsidian/issues/151) |
14+
| Git checkpoints (`checkpoint`) | Linux and macOS only | No |
15+
| Bash setup scripts and shell test suites | Yes | No (POSIX-only) |
16+
17+
Vaults must live on a filesystem with stable file identity: NTFS is fine, but
18+
FAT/exFAT volumes (typical USB sticks) and some network shares are refused with
19+
`UNSAFE_VAULT_IDENTITY` — move the vault to NTFS or work inside WSL.
20+
21+
## Why writes require WSL
22+
23+
Mutation safety is bound to POSIX directory descriptors: the vault root and
24+
every runtime directory stay pinned for the whole write, so a concurrently
25+
swapped symlink or replaced folder fails closed instead of redirecting the
26+
write (see the [compound vault guide](compound-vault-guide.md)). Native Windows
27+
cannot provide those primitives, so writes are refused up front rather than
28+
silently running with weaker guarantees.
29+
30+
A degraded native-Windows write mode — default-off, behind an explicit
31+
reduced-guarantees flag — is under consideration in
32+
[#151](https://github.com/AgriciDaniel/claude-obsidian/issues/151). If WSL is a
33+
blocker for you, that issue is the place to weigh in.
34+
35+
## WSL troubleshooting
36+
37+
WSL being "installed" does not always mean WSL is working. Symptoms and checks,
38+
roughly in the order worth trying:
39+
40+
| Symptom | Check |
41+
|---|---|
42+
| `wsl --install` completed but `wsl --status` or `wsl -l -v` hangs indefinitely | This is usually a virtualization conflict, not a claude-obsidian issue. Work through the virtualization checklist below. |
43+
| `wsl` reports a kernel or version error | Run `wsl --update`, then `wsl --shutdown`, then retry. |
44+
| WSL worked before and stopped after an update or new security software | Check whether memory integrity / Virtualization-Based Security settings changed; VBS and other hypervisors can conflict with the Hyper-V platform WSL 2 depends on. |
45+
| Approval hash from a native dry-run fails inside WSL with `PLAN_CHANGED` | By design: the approval hash binds the reviewing environment's filesystem identity. Run the dry-run review inside WSL when the apply will happen there; a natively produced `approved_plan_sha256` cannot be replayed from WSL. |
46+
| Writes fail with `UNSAFE_VAULT_IDENTITY` mentioning stable file identity | The vault sits on FAT/exFAT or an unsupported network share. Move it to NTFS, or keep it inside the WSL filesystem. |
47+
48+
Virtualization checklist for the hang class:
49+
50+
1. Confirm virtualization is enabled in BIOS/UEFI (often "Intel VT-x",
51+
"AMD-V", or "SVM").
52+
2. Confirm the Windows features "Virtual Machine Platform" and "Windows
53+
Subsystem for Linux" are both enabled, and reboot after enabling them —
54+
the reboot is not optional.
55+
3. Run `wsl --update` from an elevated prompt, then `wsl --shutdown`, then
56+
retry `wsl --status`.
57+
4. Check that the Hyper-V "Host Compute Service" (`vmcompute`) is running;
58+
restart it if stopped.
59+
5. If hangs persist, look for conflicts between Virtualization-Based Security
60+
(memory integrity) or third-party hypervisors and the Hyper-V platform —
61+
this conflict class is hardware- and configuration-specific and can survive
62+
reboots until the conflicting feature is reconfigured.
63+
64+
## Working across the boundary
65+
66+
The supported native-Windows workflow is: inspect and review natively, mutate
67+
inside WSL. Because approval hashes bind to the environment that produced
68+
them, do the reviewed dry-run in the same environment that will run the apply.
69+
Keeping the vault inside the WSL filesystem (rather than on a mounted Windows
70+
drive) avoids both the identity caveats above and cross-boundary performance
71+
overhead.

skills/wiki/references/operation-transactions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ I/O, so replacing a public root, metadata, transaction, operation, or backup
9898
entry cannot redirect reads, writes, rollback, or cleanup outside the selected
9999
vault. This confinement requires POSIX directory descriptors and
100100
`fcntl.flock`; Windows users must run the skill under WSL rather than native
101-
Windows or Git Bash.
101+
Windows or Git Bash (setup and troubleshooting: `docs/windows-wsl.md`).
102102

103103
## Required coupled writes
104104

tests/test_windows_compat.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ def test_apply_refused_before_any_side_effect() -> None:
314314
"UNSUPPORTED_PLATFORM", apply_bundle, vault, operation
315315
)
316316
assert "WSL" in str(exc)
317+
assert "docs/windows-wsl.md" in str(exc), "refusal must point at the guide"
317318
assert not (vault / ".vault-meta").exists(), "refusal must be side-effect free"
318319
assert not (vault / "wiki" / "A.md").exists()
319320

0 commit comments

Comments
 (0)