NEC-314: A canvas kept a conflict copy no edit caused: two vaults rewrote 36 order keys at once #313

Merged
nectenda-agent merged 6 commits from worktree-nec-314-a-canvas-kept-a-conflict-copy-no-edit-ca into main 2026-10-21 16:01:10 +01:00
Collaborator

Task: NEC-314 — https://projectron.nerchure.com/tasks/334

When two vaults captured a canvas at once, an order write gave new stacking keys to every card outside the longest run that kept its base order, even where the document's keys already gave the value's order. The colliding writes made SAFE-A14 keep a conflict copy nobody's edit caused (canvas hardness seed 1584194348). applyOrder now keeps any key that already sits where the value has it (new rule SAFE-A49), and an apply that rewrites more than three existing keys logs the value, base and document order by id. The replay's log showed the remaining rewrites come from Obsidian's own stacking arriving as the edit's value, which SAFE-A49 cannot stop. That follows up as NEC-324, so this is a partial mitigation; sync-limitations.md says so. Canvas hardness hour passed (seed 1203436989, 60 min, 255 rounds, B on Obsidian 1.13.7). Rides along NEC-327: a markdown-links e2e test now waits for both links before reading them.

Spec: docs/changes/NEC-314-order-keys-rewritten/spec.md

Also fixes NEC-327: markdown-links e2e reads the reading view's links before Obsidian has drawn them

Changelog

A canvas edited in two vaults at once no longer rewrites the stacking of cards that were already in the right order, so fewer conflict copies appear when nobody made a conflicting edit.

Task: NEC-314 — https://projectron.nerchure.com/tasks/334 When two vaults captured a canvas at once, an order write gave new stacking keys to every card outside the longest run that kept its base order, even where the document's keys already gave the value's order. The colliding writes made SAFE-A14 keep a conflict copy nobody's edit caused (canvas hardness seed 1584194348). applyOrder now keeps any key that already sits where the value has it (new rule SAFE-A49), and an apply that rewrites more than three existing keys logs the value, base and document order by id. The replay's log showed the remaining rewrites come from Obsidian's own stacking arriving as the edit's value, which SAFE-A49 cannot stop. That follows up as NEC-324, so this is a partial mitigation; sync-limitations.md says so. Canvas hardness hour passed (seed 1203436989, 60 min, 255 rounds, B on Obsidian 1.13.7). Rides along NEC-327: a markdown-links e2e test now waits for both links before reading them. Spec: `docs/changes/NEC-314-order-keys-rewritten/spec.md` Also fixes NEC-327: markdown-links e2e reads the reading view's links before Obsidian has drawn them ## Changelog A canvas edited in two vaults at once no longer rewrites the stacking of cards that were already in the right order, so fewer conflict copies appear when nobody made a conflicting edit.
applyOrder kept the longest run of ids in their base order and rekeyed
the rest, even where the document's keys already gave the value's order.
A base stacked another way rewrote keys that changed nothing, and two
vaults doing it at once kept a conflict copy no edit caused.

Task: NEC-314
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UFM2Q1wfJ1aApWMR7fxcwK
An apply that rekeys more than three cards logs the value's, the base's
and the document's order by id, so the next occurrence names the base
the failing run could not.

Task: NEC-314
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UFM2Q1wfJ1aApWMR7fxcwK
Found in review: two ids with equal keys could both be kept, ranked
apart by id, and an id the value put between them landed after both.
They now share a rank, so at most one stays. The log counts only cards
that already had a key, so a fill is not reported.

Task: NEC-314
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UFM2Q1wfJ1aApWMR7fxcwK
NEC-316 landed SAFE-A48 on main first, for a save read in where the
document stood over it. The order-key rule this branch adds takes the
next id.

Task: NEC-314
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UFM2Q1wfJ1aApWMR7fxcwK
The order log says the edit's value, Obsidian's own stacking, is what is
out of step, not a stale base. SAFE-A49 lands as a partial mitigation; the
cause follows up as NEC-324.

Task: NEC-314

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UFM2Q1wfJ1aApWMR7fxcwK
Wait for a note's links, not only its image, before reading them
Some checks failed
Release note / release-note (pull_request) Successful in 34s
CI / build (pull_request) Successful in 9m7s
CI / e2e (pull_request) Failing after 13m41s
CI / promote (pull_request) Has been skipped
950b8d05a4
The reading view draws in sections, so the embedded image can be in place
before the paragraph with the links is. The test read the links 36 ms after
the image appeared and found none, in NEC-314's first gate run.

Task: NEC-314
Also-fixes: NEC-327

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UFM2Q1wfJ1aApWMR7fxcwK
cruelacid force-pushed worktree-nec-314-a-canvas-kept-a-conflict-copy-no-edit-ca from 950b8d05a4
Some checks failed
Release note / release-note (pull_request) Successful in 34s
CI / build (pull_request) Successful in 9m7s
CI / e2e (pull_request) Failing after 13m41s
CI / promote (pull_request) Has been skipped
to 846b7d7c18
All checks were successful
Release note / release-note (pull_request) Successful in 18s
CI / build (pull_request) Successful in 5m59s
CI / e2e (pull_request) Successful in 13m38s
CI / promote (pull_request) Has been skipped
CI / build (push) Successful in 6m12s
CI / e2e (push) Successful in 12m35s
CI / promote (push) Successful in 32s
2026-10-21 15:46:12 +01:00
Compare
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
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!313
No description provided.