A device edits a record while disconnected and the far side changes the same record - what must the case pin down about the resolution?
answer
- Construct the divergence, never wait for it
- The recorded rule is the oracle
- Name the fate of the losing edit
- Read both sides and require agreement
- Same verdict on every single run
basics
~20 sFour things: how the divergence was constructed, which value the written rule says survives, what became of the losing edit, and that device and far side agree afterwards. Assert the recorded rule, never the behaviour you happened to observe.
solid answer
~50 sConstruct the divergence so the case is repeatable: seed the record, let the device synchronise, take the link away, edit the field locally, change the same field on the far side through a service interface, then restore the link. Now assert against the rule the team wrote down rather than against what the build happens to do. If the rule is that the latest change by a single clock survives, pin that expected value; if the rule is that the user reconciles it, pin the prompt and both candidate values. Then assert the fate of the losing edit explicitly - discarded, kept as a second version, or queued for reconciliation - and finish by reading both the device and the far side and requiring them to agree. A case that only checks the application did not crash is not a conflict case.
code
pseudocode · 18 linescase "device and far side edit the same field":
seed_order({id: "o-77", note: "original"})
sign_in()
await(until: sync_idle, deadline: 30s)
link.disable()
ui.set_note("o-77", "typed on the device") # local branch
service.patch_order("o-77", note: "changed remotely") # remote branch
link.enable()
await(until: pending_count() == 0, deadline: 60s)
# recorded rule: the far side wins, the loser is kept as a copy
expected = "changed remotely"
assert service.get_order("o-77").note == expected
assert ui.note("o-77") == expected # both sides agree
assert ui.superseded_versions("o-77") == ["typed on the device"]
assert ui.conflict_notice_shown() == truego deeper
Be ready to describe how one record ends up with two different values - one typed on a device with no connection, one changed centrally - and why somebody has to decide which survives.
Explain how you construct that divergence deliberately, and why the expected outcome comes from a rule the team recorded rather than from running the application and writing down what happened.
Show that you assert the loser's fate and the agreement of both sides, and that you keep the verdict identical across runs when the rule depends on ordering or on a clock.
Own the decision the case depends on: which side survives, whether discarding an edit is ever acceptable, and what the product owes a user whose work could not be reconciled.
When a record is edited on a device that has no connection and the same record is changed on the far side before the device returns, the product must decide something. A case about that moment is worth writing only if it pins down what was decided, in a way that survives the next change to the machinery underneath. Most weak versions of this case fail on one of two counts: the divergence happens by luck rather than by construction, or the expected result was copied from the behaviour that was observed the first time it ran. ## Manufacture the divergence; never wait for it The case owns both branches, so it should create both explicitly: 1. Seed the record through a service interface with a value the case chose, and let the device synchronise so it holds that value. 2. Take the link away with a control the run owns, and confirm it is down. 3. Edit the field on the device. That is the local branch. 4. Change the same field on the far side through a service interface. That is the remote branch. 5. Restore the link, and wait on an observable condition - outstanding work reaches zero, an idle signal is raised - rather than a fixed pause. Every step is under the case's control, so the same divergence is reproduced on every run. A case that hopes two edits collide because a background process happened to be slow is measuring scheduling, not resolution. ## Four things the case must pin down - **The surviving value.** Which of the two the product ends up holding, stated in advance. - **The fate of the losing edit.** Discarded, preserved alongside as a second version, or held for the user to reconcile - all three are legitimate designs and they are not interchangeable. - **Agreement.** The device and the far side must end up on the same value; read both, because one of them alone hides half the failures. - **What the user is told.** If a version of their work was dropped, silence is a design decision someone has to own, and the case should assert whatever was chosen. ## The written rule is the oracle The expected value comes from a rule the team recorded, not from running the application and writing down the result. That distinction is the whole professional content of the question: recording current behaviour produces a case that defends a bug as loyally as it defends a feature. | Recorded rule | Expected surviving value | What the case asserts about the loser | | --- | --- | --- | | Latest change by a single clock wins | The later of the two, by that clock | Gone, and the user is notified | | The far side always wins | The remote value | Local edit preserved as a copy | | Per-field merge where fields differ | Both changes present | Nothing was lost; assert each field | | The user resolves it | Neither, until a choice is made | Both candidates offered on screen | If nobody can tell you which row applies, that is the finding. Produce the divergence by hand, show the outcomes the product could plausibly have, and make someone choose. The choice becomes the expectation; the case then defends it against regression forever after. ## Determinism when clocks or arrival order decide Where the rule leans on time, the case must control the inputs the rule reads rather than racing real time. Complete the local edit before the link is restored. Apply the far-side change at a moment the case picks. Where the values are supplied by the caller, seed them; where they are stamped on arrival, order the arrivals. The test of a good conflict case is simple: run it twenty times and it gives the same verdict twenty times. If it flips, it is not telling you about resolution - it is telling you which branch got there first today, and that is not a property anyone agreed to. ## Why a case that only checks for a crash is close to worthless The failure everyone actually fears is silent data loss, and losing an edit crashes nothing. The screen looks fine, no error is raised, and the user finds out days later that the note they typed on a train never existed. An assertion that the application is still running is satisfied equally by correct merging and by throwing the work away, which is why the surviving value, the loser's fate, the agreement of both sides and the notification are the four assertions worth having. ## What this case does not own It does not design the resolution strategy, the delivery mechanism, or the scheduling that decides when reconciliation runs. Those are architecture questions with their own home, and a behavioural case that encodes their internals breaks every time they are tuned. This case treats the decision as a stated contract and proves the product honours it - which is precisely what lets the machinery beneath be rewritten with confidence.
- Nobody wrote the rule down - the team says whatever the mechanism does is fine. What do you do?Stop and get it decided, because without a rule the case can only record current behaviour and will defend whatever bug exists today. Produce the divergence by hand, demonstrate the outcomes the product could plausibly have, and make someone choose between them. That choice becomes the expectation, and the case then protects it against regression.
- Why is a conflict case that asserts only that nothing crashed close to worthless?Because the failure people care about is silent data loss, and losing an edit crashes nothing. Absence of a crash is satisfied equally by a correct merge and by discarding the user's work. The assertions that earn their place are the surviving value, the loser's fate, the agreement of both sides, and whatever the user is told.
- How do you keep the divergence deterministic when the rule depends on ordering or time?Control the inputs the rule reads instead of racing them. Finish the local edit before restoring the link, apply the far-side change at a moment the case chooses, and where values are stamped on arrival, order the arrivals. If the verdict can flip between runs, the case is measuring scheduling rather than resolution.
saying these in an interview costs you the question
- Expected value copied from the first observed run
- Asserts only that the application did not crash
- Lets the divergence occur by timing luck
- Never states what happened to the losing edit
- Reads only the device after reconciliation
- Accepts silent loss of the user's work