Status & Drift Detection

dropbear status <path> is the health-check surface. It reports five things about a root: who the root is, what's in local state, what's in conflict, what other devices are publishing, and whether anything has drifted between local state and the bucket.

The command makes one bucket round-trip (head fetch per device + one full blob list) and no writes. Safe to run any time.

What it shows

root        photos
device      laptop  (mode: bidirectional)
identity    online

files       48 total
            42 clean
             3 new
             1 modified
             2 conflict

conflicts   2
  shared.txt
    from    dev-desktop @ 2026-05-22T18:00:00Z
    copy    shared.conflict-dev-desktop-20260522T180000Z.txt
  notes/meeting.md
    from    dev-desktop @ 2026-05-22T17:30:00Z
    copy    meeting.conflict-dev-desktop-20260522T173000Z.md

devices     2 known, 0 skipped
  dev-desktop   manifest 20260522T180500Z  (2026-05-22T18:05:00Z)
  dev-phone     manifest 20260520T091200Z  (2026-05-20T09:12:00Z)

drift       OK

When the root is offline, the output collapses to just the identity section — status doesn't try to read the bucket if it can't even validate the root.

Reading the sections

identity is the same check dropbear status always did. online means root.toml parsed and root_id matches; anything else means the rest of the report is skipped.

files is a count-by-status from state.sqlite. new and modified are pending uploads; deleted is pending tombstones; conflict are paths that need manual resolution. A conflict count above zero is the signal that you have work to do.

conflicts is the list of paths in StatusConflict. For each path, status scans the file's directory for .conflict-<other-device-id>-<ts> siblings, parses the device id and timestamp from the basename, and reports them. There can be more than one conflict copy per path if multiple other devices have diverged at different times.

devices enumerates every other device's head in the bucket. Each line shows the device id, its latest published manifest id, and when that manifest was written. A device counted under skipped means status couldn't fetch that device's head — transient I/O, auth, or a head that won't decode.

drift is the bucket-vs-state cross-check. The "OK" case means every blob referenced by your own latest manifest, and by every reachable remote manifest, is actually present in the bucket. Issues fall into four kinds:

  • blob-missing — a manifest entry whose sha256 is not in the bucket. This is the "phantom manifest entry" shape: a published manifest claims a blob exists, but the blob was never uploaded (or has since been deleted). Edit and re-save the affected file to repair.
  • head-fetch-failed — another device's head fetch errored. That device's contribution to drift is silently dropped for this run; the device is otherwise still listed.
  • manifest-fetch-failed — another device's head fetched fine but its manifest didn't (404, parse error, hash mismatch).
  • blob-list-failed / store-open-failed — bucket-level errors before drift could be computed.

--json output

$ dropbear status --json ~/Pictures
{"schema_version":1,"root_path":"...","root_id":"photos","device_id":"laptop","mode":"bidirectional", ...}

Shape follows the same schema_version=1, snake_case, optional-pointer convention as dropbear sync --json. Sections that don't apply (e.g. file_counts, devices, drift when offline) are omitted entirely. Drift issues are an array of {kind, path?, sha256?, device_id?, detail} objects.

Exit codes

status exits with the same code as the underlying identity check — 0 when online, non-zero (per the existing config.ExitCode mapping) when offline / identity-mismatch / corrupt. Drift on its own does not make the command exit non-zero; status is observational, not gating. If you want a non-zero exit for CI-style "fail when drift detected" checks, parse the JSON.

When to run it

  • After a manual surgery on the bucket. Drift will tell you if you broke a reference.
  • Before deciding whether to keep another device on bidirectional or move it to download-only. The devices listing + last-published timestamp shows you who's actually contributing.
  • When sync complains about conflicts. status gives you the per-path list with the conflict-file copies named explicitly.
  • As a smoke test after upgrading dropbear. A clean status (drift OK, no surprise conflicts) means the upgrade hasn't broken anything you'd notice.