Concurrent Workspace Mutations

Tracked by pm-bgcu. Power-loss durability is governed by pm-o2kc.

The CLI and MCP use the SDK's persistence primitives. Atomic replacement makes one file write indivisible, but preserving concurrent edits also requires protecting the read and decision that precede that write.

Settings snapshots

readSettings attaches an internal, non-enumerable persistence snapshot. writeSettings compares the caller's edited snapshot with the latest document while holding the workspace-history lock. Changes to different object keys are combined, including separate keys in a newly introduced nested object. Unchanged keys keep the current persisted values; sparse defaults and file-backed schema definitions remain sparse.

Concurrent incompatible edits to the same scalar, array, or deleted object return a conflict before writing. Read a fresh settings snapshot and reapply the intended operation. Equal concurrent changes are idempotent. A successful write advances that instance's baseline, so reusing it cannot replay an earlier edit over another writer. Conflict messages name keys without exposing values. Deleting the settings document also invalidates an unchanged read snapshot; its next write returns the same structured conflict.

Keep the object returned by readSettings when editing settings. Constructing a new object, spreading it, or using structuredClone drops the internal snapshot; writeSettings treats such objects as explicit whole-document replacements. They are suitable for initialization, not concurrent edits.

The same lock protects the persisted document, its workspace history entry, and compensation if history append fails. This prevents concurrent writers from forking the chain or leaving an accepted write unrecorded. It does not claim crash atomicity across separate filesystem writes.

Schema, session, and rollback state

Schema mutations hold the existing schema-types, schema-statuses, or schema-fields lock while reading and modifying their file. Profile application uses the same lock order. Bootstrap stages complete seed bytes and publishes them through a non-replacing hard link: a concurrent schema writer or reader can never be overwritten by a delayed bootstrap. A filesystem that refuses hard links returns an error instead of falling back to an unsafe overwrite.

Focus and semantic attribution share the session-state lock across the full read-modify-write operation. Independent agents retain their attribution while focus changes. This state remains local and ephemeral.

Rollback checkpoints use the same atomic, non-replacing publication as schema seeds. Filesystem identity also protects paths reached through symlink aliases. A byte-identical retry succeeds; reusing an ID for different contents fails without replacing the original rollback evidence. Different checkpoint paths remain independent.

Atomic publication guarantees complete visible bytes and prevents replacement. It does not flush file data or directory entries to stable storage, so success does not guarantee survival of power loss. A stronger durability policy must cover all writers, newly created ancestor directories, retry acknowledgements, and supported filesystems; syncing only this publication path would not establish that workspace-wide guarantee.

The mutation locks use the existing bounded contention and stale-owner recovery mechanism. Settings use configured lock TTL and wait values. Internal session locks use the standard defaults; PM_LOCK_WAIT_MS still overrides their wait budget. Every acquired lock is released on success and failure.


Workspace_concurrency remote
报告问题