# SyncLedger (CLI prototype)
SyncLedger is a real, working push/pull sync tool that talks to a remote
SyncLedger server over plain HTTP with shared-secret token auth and an
append-only JSON-lines audit ledger of every transfer -- the genuinely
different network transport layer versus the local-filesystem-only
sibling tools SyncGuard (one-way mirror) and FolderSync (versioned
sync), aimed at NAS users, creative studios, and distributed small
teams who need to push files to a machine that isn't the one they're
sitting at. Both sides of the protocol -- the `serve` endpoint and the
`push`/`pull` client logic -- are implemented here using only Go's
stdlib `net/http`, so one instance of this binary can sync against
another instance of itself with no third-party server involved.
## Build from source
Requires Go 1.24+, no external dependencies.
go build -o syncledger .
Cross-compile, e.g. for Windows:
GOOS=windows GOARCH=amd64 go build -o syncledger.exe .
(swap GOOS/GOARCH for darwin/amd64, darwin/arm64, linux/amd64, etc.)
## Usage
syncledger serve
--port 8080 --token SECRET
syncledger push --remote http://host:port --token SECRET --ledger ledger.jsonl [--apply]
syncledger pull --remote http://host:port --token SECRET --ledger ledger.jsonl [--apply]
syncledger help
### serve
Runs a real HTTP server (blocking, until interrupted) rooted at ,
implementing the three endpoints described below.
--port Port to listen on (default 8080).
--token Shared secret required on every request (see Auth).
### push
Fetches the remote's manifest, computes real SHA-256 hashes of every
file under , and compares the two by hash: any local file
that is new or whose hash differs from the remote copy is queued for
upload. Files whose remote copy already matches are skipped, so
re-running push after a successful run is a fast no-op (resumable, same
philosophy as the local-sync siblings).
--remote Base URL of a running "syncledger serve" instance.
--token Shared secret sent as the X-Sync-Token header.
--ledger Audit ledger to append to (default:
/ledger.jsonl).
--apply Actually upload the files. Without it, push only
prints the plan (dry run) and changes nothing on
either side.
### pull
The mirror image of push: fetches the remote manifest, compares it
against , and downloads any remote file that is new or
different, writing it locally. Files already matching locally are
skipped. Same --remote/--token/--ledger/--apply flags, same dry-run
default.
## Protocol
Designed to be as simple as possible while still being real:
GET /manifest
Returns the server directory's full checksum manifest as JSON:
{"files":[{"path":"rel/path","size":123,"sha256":"..."}]}
GET /file?path=rel/path
Downloads that one file's raw bytes.
PUT /file?path=rel/path
Uploads a file: request body is the file's raw content. The
server creates any missing parent directories and writes the
file (via a temp file + atomic rename so a crash mid-upload
never leaves a corrupt file in place).
Paths are always relative, slash-separated, and validated server-side
against directory traversal ("..", absolute paths) before being joined
to the server's root.
## Auth
Both `serve` and the client commands take a `--token` value. The
server checks the `X-Sync-Token` request header against that value on
every request to all three endpoints (including /manifest) and
responds `401 Unauthorized` on any mismatch or missing header -- a
minimal but real access control, not an open file server.
## Audit ledger
Every file actually transferred with `--apply` is appended as one JSON
line to the ledger file:
{"path":"notes.txt","size":512,"sha256":"...","direction":"push","timestamp":"2026-08-10T02:22:11Z"}
`direction` is "push" or "pull" depending on which command performed
the transfer. Dry runs (no --apply) never write to the ledger.
## Roadmap
This prototype proves the core mechanism: a real client/server file
sync over HTTP with checksums, resumability, token auth, and an audit
trail. It intentionally does not include: integration with real cloud
providers or NAS protocols (S3, SMB, WebDAV), TLS/HTTPS termination,
multi-user accounts, scheduling/watch-mode, or a conflict-preview UI.
Those are on the roadmap for the full product concept -- see
../plan.md for the complete plan.
## Prebuilt binaries
See ../downloads/ for prebuilt binaries (Windows/macOS/Linux) and
CHECKSUMS.txt for their SHA-256 hashes. Unsigned indie builds --
Windows SmartScreen and macOS Gatekeeper will warn on first run,
expected until a code-signing certificate is in place.