fix: preserve staged notes and installed customer context (5.1.18) - #159
Conversation
| const stem = `${compact}-${source}-${titleSlug}` | ||
| let id, dest | ||
| // Serialize name selection with the write: two agents can stage in one second. | ||
| withFileLock(path.join(box, '.stage'), () => { |
There was a problem hiding this comment.
🟡 Concurrent first staging rejects notes
During concurrent first-time staging, withFileLock starts after both processes can race to create the absent inbox. One mkdirSync can receive EEXIST, aborting that note instead of assigning a suffix.
Learn more
Inbox creation occurs before the shared staging lock. checkedInbox returns null when the inbox is absent, and each process then calls fs.mkdirSync(box) independently. If two processes observe the missing directory, the first creates it and the second receives EEXIST; the outer catch exits through failFs before filename selection begins.
Example: Two MCP clients simultaneously stage the first notes for Atlas. Both see no .inbox; client A creates it, while client B fails with EEXIST. Only A's note reaches the suffix-selection lock, although both notes had distinct content.
Recommended fix: Create the inbox with race-safe semantics, such as fs.mkdirSync(box, { recursive: true }), then validate it with checkedInbox(eng). Alternatively, serialize directory creation using a lock whose parent already exists. Add a barrier-based regression that forces both processes past the absence check before either creates the directory.
Was this helpful? React with 👍 or 👎 to provide feedback.
Preserve staged notes when multiple inputs share a timestamp, source and title: select a free filename under a shared staging lock before writing. Make installer
inithonor the same engagement-root setting as the CLI, preventing a second empty customer record on bind. Ship CLI version metadata and keep privacy guidance available on older disk installs without it.Regression coverage exercises sequential and concurrent staging, custom and tilde roots, and the installed CLI rather than only the source checkout. All 458 repository tests passed; independent review found no issues. Structural and focused tests passed again with release metadata set to 5.1.18.
Only the three fixes, product regression tests, version metadata and changelog are included.