GeoLeaf Core API - v3.19.0
    Preparing search index...

    Type Alias ConflictPolicy

    ConflictPolicy: "lastWriteWins"

    Conflict policy — frozen as lastWriteWins, and DECLARED rather than defaulted.

    This is what the code already does, but by accident: every strategy fell through to a forced overwrite. The change is not the outcome, it is that the conflict becomes detectable and logged, because the push now carries baseVersion.

    The rationale is the field: an operator is the authority on what they have just observed, and a blocking dialog raised offline, alone on site, gets clicked at random.

    ⚠️ A SECOND type describes the same arbitration, under another name and in another package: ConflictStrategy (@geoleaf-plugins/editor, persistence/conflict-resolution.ts), which is "client-wins" | "server-wins" | "prompt". Neither the compiler nor any gate can flag that they speak of the same thing: two differently-named types on either side of a package boundary, which is also a review boundary.

    The split as MEASURED on 17/08/2026 — each governs its own path, no hierarchy:

    Path Governed by Applied in
    offline drain (outbox queue) ConflictPolicy capabilities/offline/write/push-engine
    interactive submission (form) ConflictStrategy editor — persistence/submit.ts

    🛑 What this split produces, and what was written nowhere: an integrator who sets modules.editor.persistence.conflictResolution: "prompt" does get a prompt on the interactive path — and does NOT get one on the offline drain, which decides by lastWriteWins without consulting it. Measured: push-engine.ts carries no reference to conflictResolution nor to ConflictStrategy. That is not a defect — it is even the deliberate motive recalled above (a blocking prompt raised offline, alone in the field, gets clicked at random). But it happens silently, and that is the one thing the relationship between the two types had to say.

    📌 Neither "wins" over the other — the question "which one wins when the two paths cross" is not decided here, and it is named rather than invented: deciding it would mean choosing whether a replayed offline capture should reopen a prompt after the fact. Not instructed, not urgent, no requester.

    ⚠️ ConflictPolicy has NO consumer in source: the policy is applied by the BEHAVIOUR of push-engine.ts (which names it in its log), not by a reference to the type. The type declares the intent; it does not enforce it. Knowing that prevents believing that changing its value would change anything.