Repository navigation
Align a comparison on what did not change, and refuse an identical version - #93
Merged
Merged
Conversation
…rsion Side by side becomes the default for every rendered comparison and the layout is remembered across a version switch, because a reader who picked one and then moved between versions was handed back the default they had just rejected. The swipe stays one click away, and its slider is hidden wherever it would do nothing. The scroll sync anchors on paired unchanged content instead of page fraction. Two versions have different heights, so a fraction puts the same paragraph in two places: measured on a framed pair, 117 pixels out. The diff now pairs identical nodes as well as changed ones, in its own id namespace, and the frame guard accepts both namespaces. Accepting only one silently dropped most messages and left the follower still. A change navigator carries prev, next, a position, and a sidebar list whose rows jump. Each stop scrolls the pane that actually holds the change, since an addition exists in one version and a removal in the other. Before the diff lands it says it is comparing, never that there are no changes. A republish whose bytes, filename and title match the live version is refused locally, before any request. The client records a digest of that plaintext on each publish; the service cannot answer the question, because it holds ciphertext under a fresh salt per object. An entry written before the digest cannot be compared, republishes once on that ground, and records one as it lands.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Jason, on the comparison view:
Four of those are the comparison view. The fifth is the publish client.
What changed
Side by side is the default, and the layout is remembered. Swipe shows pixels moving but never both readings at once, so comparing prose meant remembering the left to judge the right. Swipe stays one click away for positional changes, and its slider is hidden in every layout where it does nothing. The choice survives a version switch through
localStorage; before this, picking a layout and then moving between versions handed back the default that had just been rejected.The scroll sync anchors on unchanged content. Two versions have different heights, so aligning by page fraction puts the same paragraph in two places, and the error grows with the size of the edit. Measured on the framed fixture: a version with two inserted paragraphs sat 117 pixels out. The diff now pairs identical nodes as well as changed ones, in its own id namespace, and the follower scrolls the paired node.
A change navigator, with every change addressable. Prev, next, a position that says which of how many, and a list in the sidebar whose rows jump. Each stop scrolls the pane that actually holds the change, because an addition exists in one version and a removal in the other, and asking the pane without it jumps to nothing. Before the diff has run it says it is comparing rather than claiming there are no changes.
An identical republish is refused, locally, before any request. The client keeps
content_sha256in publish state: SHA-256 over the bytes, the envelope filename and the plaintext title, so a retitle is a real version and a re-upload of the same file is not. The service cannot answer this question and is never asked, because it holds ciphertext under a fresh salt per object. It sits above the comment gate, which is the first thing in that path to touch the network, since an unchanged file is also the likeliest reason comments are still open.Three defects the browser found, that the tests could not
Also found while proving: the navigator claimed "No changes" before the diff had run, which reads as a finished comparison of two identical versions.
Proof
Driven in Chrome against a seeded service, on two fixtures.
Markdown pair, four changes: each of the four stops lights exactly one node, in the correct pane, at the correct scroll position, and the sidebar rows jump.
Change 1 of 4throughChange 4 of 4.Framed HTML pair, tall enough that the ends-safe fallback is not in play: 41 anchors painted on both sides, and scrolling paragraph 20 to the top of the newer version puts paragraph 20 at the same offset in the older one. Error 0 pixels, where page fractions would have been 117 out.
Layout: chosen swipe survives a version switch and a rebuild; switching back to split survives too; the slider is present only in swipe.
Duplicate refusal:
describe('duplicate versions')in the MCP e2e suite, five cases, mutation-proved. Removing the gate fails four; trusting a malformed digest fails the fifth. An identical republish is refused with zero fetch calls.Full gate: 1455 tests, 0 fail.
One gap
The duplicate refusal ships in the
relic-mcpnpm package, which publishes on a separate manual trigger. Merging does not put it in anybody's installed client; I will publish after merge and prove it through the published client against the live service, the same way as the version scoping.