DirectoryTreeHandle is stale after write operations

did:plc:wydyrngmxbcsqdvhmd7whmye opened this Mar 20, 2026 0 comments
did:plc:wydyrngmxbcsqdvhmd7whmye opened Mar 20, 2026

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 = null
  • web/src/workers/api/pds.ts — write operations (directoryCreate, directoryAddEntry, etc.) make PDS calls but have no reference to the tree handle
  • crates/opake-wasm/src/lib.rs:519-626DirectoryTreeHandle exposes only read-only methods (no addEntry, 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:

  1. Add mutation methods to DirectoryTreeHandle in Rust and call them from pds.ts after write operations
  2. 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.

No activity yet.

cospan · schematic version control on atproto built on AT Protocol