Summary#
The Web Worker holds a stateful DirectoryTreeHandle (module-level variable in web/src/workers/api/tree.ts). Write operations like directoryCreate, directoryAddEntry, and directoryRemoveEntry update the PDS but do not update the in-memory tree handle. The handle becomes a stale snapshot.
Impact#
Currently dormant — every write operation in the documents store calls loadCabinet() afterward, which does a full rebuild from fresh PDS records. The bug would manifest if code queries the tree handle between a write and the rebuild, or if a future optimization skips the rebuild.
Location#
web/src/workers/api/tree.ts:12-13— stateful handle:let directoryTree: DirectoryTreeHandle | null = nullweb/src/workers/api/pds.ts— write operations (directoryCreate,directoryAddEntry, etc.) make PDS calls but have no reference to the tree handlecrates/opake-wasm/src/lib.rs:519-626—DirectoryTreeHandleexposes only read-only methods (noaddEntry,removeEntry, etc.)
Structural proof#
DirectoryTreeHandle has no mutation API:
snapshot(),rootUri(),entriesFor(),directoryName(),isDirectory(),findParent(),countDescendants(),collectDescendants(),free()- No
addDirectory(),removeEntry(), or similar
The only way to reflect changes is buildDirectoryTree() with fresh records from the PDS.
Proposed fix#
Either:
- Add mutation methods to
DirectoryTreeHandlein Rust and call them from pds.ts after write operations - Accept the full-rebuild pattern and document it as intentional (the rebuild is cheap — directory records are small)
Regression test#
web/tests/bugs/tree-sync.test.ts — builds a real WASM tree handle, simulates a write, queries the handle, proves it's stale. 3 test cases.