NEC-284: A tab reused twice within a moment backs up typing with no reason, in a round with no conflict #294

Merged
nectenda-agent merged 3 commits from worktree-nec-284-a-tab-reused-twice-within-a-moment-backs into main 2026-10-14 23:42:40 +01:00
Collaborator

Task: NEC-284 — https://projectron.nerchure.com/tasks/295

When the plugin lets go of an editor, it now saves it first. Obsidian merges a file change into a view with unsaved text three ways against what that view last loaded or saved; a collaborator's line reaches a bound editor through yCollab, so that base predates the line until Obsidian's own save about two seconds later. Let go of in that window, for a second tab reused for the note, the view kept the stale base, and Obsidian's save of the second tab was merged into it as a second copy of the line: bound again at once, its typing went to a backup for no reason (the Markdown hardness run, seed 196796986, round 306); left unbound, its next save wrote the duplicate into every vault. New rule SAFE-B6, unit tests in editor-bridge.test.ts, two e2e cases in multi-pane.test.ts (each fails on its first attempt without the save), and the hardness replay now passes past round 306.

Spec: docs/changes/NEC-284-save-an-editor-as-it-is-let-go/spec.md

Changelog

A collaborator's line could appear twice in a note after the editor moved between two tabs on it within a moment; it is now kept once.

Task: NEC-284 — https://projectron.nerchure.com/tasks/295 When the plugin lets go of an editor, it now saves it first. Obsidian merges a file change into a view with unsaved text three ways against what that view last loaded or saved; a collaborator's line reaches a bound editor through yCollab, so that base predates the line until Obsidian's own save about two seconds later. Let go of in that window, for a second tab reused for the note, the view kept the stale base, and Obsidian's save of the second tab was merged into it as a second copy of the line: bound again at once, its typing went to a backup for no reason (the Markdown hardness run, seed 196796986, round 306); left unbound, its next save wrote the duplicate into every vault. New rule SAFE-B6, unit tests in editor-bridge.test.ts, two e2e cases in multi-pane.test.ts (each fails on its first attempt without the save), and the hardness replay now passes past round 306. Spec: `docs/changes/NEC-284-save-an-editor-as-it-is-let-go/spec.md` ## Changelog A collaborator's line could appear twice in a note after the editor moved between two tabs on it within a moment; it is now kept once.
Which pane's log a bind takes, and whether it was interrupted, decides a
backup at the bind, and the question when two tabs swap on a note is which
editor made it. The editor id moves to its own module so the bridge and the
edit recorder name an editor the same, and the hand-over is logged by
length, never text.

Task: NEC-284
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkXmWMH1zDpLmNFstQujAH
Obsidian merges a file change into a view with unsaved text three ways,
against what the view last loaded or saved. A collaborator's line reaches the
bound editor through yCollab, so that base predates it until Obsidian saves,
about two seconds later. Let go of in that window, for a second tab reused
for the note, the view kept the stale base; the second tab's save, which the
plugin cannot ask about first, was merged into it as a second copy of the
line. Bound again at once, its typing went to a backup for no reason; left
unbound, its next save wrote the duplicate into every vault.

Letting go now makes the save Obsidian was about to make, through the hook
still on the view (SAFE-B6). Both cases are e2e tests in multi-pane, and
each fails on its first attempt without the save.

Task: NEC-284
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkXmWMH1zDpLmNFstQujAH
Say what a release save does when a save is already running, and make the e2e setup fail loudly
All checks were successful
Release note / release-note (pull_request) Successful in 21s
CI / build (pull_request) Successful in 5m24s
CI / e2e (pull_request) Successful in 11m58s
CI / promote (pull_request) Has been skipped
CI / build (push) Successful in 5m32s
CI / e2e (push) Successful in 11m40s
CI / promote (push) Successful in 31s
58b01b83ba
From review. A save of the view already in flight makes Obsidian only mark
one to follow, which reads the text after the hook is off: the same text,
remembered by ContentSync as the editor's own, but a few milliseconds of the
stale base remain, now recorded as a residual. A deleted note is not written
back, since Obsidian's save returns for one. The e2e setup now throws if the
collaborator's line never reached tab 1 or the tabs are not as expected,
rather than passing without exercising anything, and the measured `set` names
its evidence.

Task: NEC-284
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkXmWMH1zDpLmNFstQujAH
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Nectenda/nectenda!294
No description provided.