Skip to content

Conflicts and incidents

Sync does not choose how to merge, rebase, or reset a repository. That choice belongs to a human or an agent acting under an explicit repository grant.

The public v1 API includes repository-scoped ref and incident views, personal acknowledgement, proof-bound checkpoint recovery, resolution intent, retry, and safe resume. These controls record and validate a decision; they do not perform a Git merge for you.

GET .../refs and GET .../incidents return pages of at most 50 rows, with 20 rows by default. Use the opaque nextCursor exactly as returned. Ref and incident detail responses include a strong numeric ETag for guarded mutations.

Incident detail reports preserved-tip counts and a preservedTipsHref. Follow that link to page through every retained observation before proposing a resolution; the detail response does not embed an unbounded tip list.

Acknowledgement is personal. GET .../acknowledge reports whether the current caller has acknowledged the incident. POST .../acknowledge requires sync:acknowledge, an Idempotency-Key, and the incident If-Match. It does not resolve, retry, or resume the incident, and it does not acknowledge it for another principal.

An eligible checkpointCorrupt incident exposes human-only recovery at POST .../recover-checkpoint. It requires sync:resolve, an Idempotency-Key, and the current incident If-Match. The request has no object-ID field: Sync retains the retired checkpoint as forensic evidence and observes both endpoints again before making another synchronization decision.

Resolution requires sync:resolve, an Idempotency-Key, the current incident If-Match, a chosen present or absent ref outcome, and an explicit disposition for every preserved tip that the chosen history omits. The server validates the resulting Git graph; clients cannot submit ancestry claims as proof.

Attempt history is ordered and retained. Retry requires sync:retry and is accepted only after the latest attempt ends in a retryable failure or outage. Safe resume requires sync:resolve and succeeds only after the chosen graph and retained recovery history satisfy the incident’s current conditions.

A 409 is a prompt to reload. Do not automatically repeat a mutation against stale state; read the current resource, obtain its new ETag, and ask the human or agent to decide again.

When both sides of one branch or tag change incompatibly from their checkpoint, Sync:

  1. pauses only the affected ref;
  2. preserves each observed head for recovery;
  3. records the observed tips and reason in an incident; and
  4. exposes the pause through the API and product UI.

Other independent refs may continue. Additional changes while the ref is paused add preserved tips instead of replacing earlier evidence. Preserved tips and the Git/LFS objects they reach are lifetime-retained, as are the incident’s attempts, acknowledgements, and dispositions.

Every immutable branch keeps the same rule during recovery: the selected tip must descend from Gitdown’s current tip for that ref. No Sync incident action bypasses Gitdown branch policy.

A normal Git divergence is ref-local. Sync quarantines the whole connection only when it cannot safely establish identity, checkpoint ownership, or history preservation. For example, a provider rewrite may make an observed tip unavailable before it can be preserved. That is a history gap rather than a merge conflict and requires explicit investigation before resume.

The product UI has no preselected resolution outcome or omitted-tip disposition. It preserves already loaded pages, requires a reason for every omitted tip, confirms mutations, and treats the server as authoritative.

Customer-configured outbound webhooks and email notifications are not yet part of the preview. Until they arrive, authorized callers can poll the incident and connection resources.