What is Synck?

This chapter is about getting going. It starts with the ideas you need to use Synck well, then installs it and walks you through your first repository and your first complete repository. If you only read one conceptual page before you start, make it this one. Most confusion about Synck comes from expecting it to behave like some other tool.

About version control

A version-control system records changes to a set of things over time, so you can see how they evolved and get back any earlier state. Most people first meet it as copies with names like proposal-final-v3-REALLY-final.docx. That works until you need to know which copy the client saw, or who changed the budget and why.

Software developers solved this long ago with tools such as Git. Those tools are excellent at what they were built for: plain-text source code, edited by many people in parallel and combined later by merging lines of text.

Version control for knowledge work

Knowledge work has a different shape. A project consists of documents, but also of a review conversation, a task with an approval, a calendar of meetings and the email sent to the client. Several things follow from that:

  • Much of it is not a file. A chat is a growing sequence of messages, not a document you save. A task has a state, an assignee and comments.
  • Identity matters more than location. People rename and reorganize all the time. A proposal that moved from Drafts/ to Sent/ is still the same proposal, with the same history.
  • Most of it cannot be merged. Two people’s edits to a spreadsheet or a slide deck cannot be combined line by line. What matters is that changes are accepted in a clear order and nothing is lost.
  • The record outlives the tools. You might need the conversation that led to a decision years after you stopped paying for the application that hosted it.

Synck is designed for that shape. The rest of this page describes the handful of ideas it is built on.

Items have identity

Synck does not version a tree of paths. It versions items. A file, a folder, a chat, a task list and a calendar are all items. Every item has a permanent ID that it keeps for life:

Repository
├── FOLDER  Launch   (a workspace)     01a174b7-8a7d-74e0-b0d7-81cf3866d6b9
│   ├── FILE  proposal.txt             01a174b7-8f4e-76f1-8ac4-440db922fb52
│   └── FILE  budget.csv               01a174b7-9089-76c2-82ae-adfd661146f1
│
└╌╌ CHAT  "Launch review"              01a174b7-8a7d-74e0-b0d7-81d946ca6792
       a non-tree item: no folder; SynckHub associates it with the workspace

Rename proposal.txt or move it into another folder and it is still item 01a174b7-8f4e-…, with its whole history attached. Delete it and create a new file with the same name, and the new file is a different item. A path tells you where an item is now. The ID tells you which item it is.

Tree items and non-tree items

Items come in two kinds, and the difference matters as soon as you look past files.

Tree items have a place in the folder tree: folders, files, and some application items such as emails and task lists. They have a parent folder (or sit at the top), a name that is unique among their live siblings, and a path. Synck enforces the tree rules for them: a folder cannot contain itself, and two live items in the same folder cannot share a name.

Non-tree items are records that have no place in a folder: chats, posts, calls, tasks, calendars, structured databases and tables, and time-tracking records. They have no parent folder and no path. A chat’s internal name is a generated identifier, such as chat-01a174b7-8a7d-…, and the name people see, such as “Launch review”, is a title stored with the item. Two chats can share a title. Smaller records inside an item, such as a chat’s messages, reactions and attachments, are not items at all. They are subitems in their parent item’s history.

Workspaces

In SynckHub, work is organized into workspaces, which an organization may call cases, matters, deals, projects or engagements. A workspace is a tree item, a folder with a workspace identity, that holds the project’s files. The project’s other records are connected to it by association, not placement. For example, a team chat can be linked to the workspace it belongs to, and access to the workspace can then extend to the chat. The chat still never becomes a child of the folder. Direct messages and assistant conversations are not linked to a workspace at all.

History is a log of events

Every change to an item is an event: the file got new content, the folder was renamed, a message was added to the chat. Each item’s events form a single numbered line, its item sequence:

proposal.txt   1 FILE::CREATE ── 2 FILE::SET_CONTENT ── 3 FILE::SET_CONTENT
Launch review  1 CHAT::CREATE ── 2 CHAT::SET_PROFILE ── 3 MESSAGE ── 4 MESSAGE ── 5 MESSAGE

A commit groups one or more events, possibly for several items, into a single change that is accepted all at once or not at all. Creating a folder and the three files inside it is one commit; if any part is invalid, none of it is recorded. Every commit is identified by a SHA-256 hash of its exact content, so it can be checked later.

This is the biggest difference from Git. Git records snapshots of the whole tree and works out what changed between them. Synck records what happened to each item and can rebuild any state from that. Items, events and commits shows the real events behind a short session.

Nearly every operation is local

A Synck repository is a folder with a .synck directory inside it. Everything Synck needs is there: the history in a SQLite database and the content in an object store. Viewing history, comparing versions, extracting an old file and verifying integrity all read local data. No account, server or network is involved. Even reading a repository exported from SynckHub does not contact SynckHub.

Synck has integrity

Every file version, message body and commit is identified by the SHA-256 hash of its exact bytes. synck fsck and synck repository verify recompute those hashes and check the history’s structure. You cannot change a stored file, a message or a past commit without the check noticing.

Hashes prove that the data is consistent. On their own, they do not prove who produced it. An author name in Synck is a label for attribution, not a login. Keep that distinction in mind when you receive a repository from someone else; copies you can trust discusses it in detail.

Synck only adds data

Accepted history is never rewritten. Editing a file adds a new version and leaves the old one in place. Deleting a file moves it to the trash, and you can recover it with its identity intact. Undoing a commit adds a new commit that reverses it. Because nothing is removed, an honest mistake is always recoverable.

The other side of this is that you cannot erase something from history by committing again. If you commit a secret, it stays in that repository’s history. Plan for that before you commit sensitive material.

One writer per item

Each item has exactly one writer authority that accepts its changes in order. In a folder you track on your own computer, that authority is you. In SynckHub, it is the server. There are no branches and no merges: two copies of a repository that are changed independently stay separate forever.

This is a real limitation, and it is intentional. Merging is what lets developers work in parallel on text, but it has no good meaning for most knowledge-work data. Synck chooses a simple, predictable rule instead: one authority, one ordered history. The trade-offs page describes what this costs and when another tool is the better choice.

One kind of repository, with or without files on disk

Every Synck repository has the same complete format. What differs is whether its files are also laid out in a folder for you to edit, a checkout:

With a checkout                         Without a checkout (bare)
(from `synck init`)                     (an export or a copy)

notes/                                  launch-project/
├── .synck/       history + content     └── .synck/   history + every byte
├── .synckignore                                       for files, chats,
├── plan.txt                                           email, tasks, ...
└── meetings/
    └── standup.txt                     Read it with `synck item`, or ask
                                        for a checkout to get files.
Edit files, then `synck commit`.
With a checkout Bare
Where it comes from synck init in a folder, or synck repository checkout An export from SynckHub, or a copy
What it holds Every kind of item: files, chats, email, tasks, calendars and more The same
Everyday commands status, commit, log, diff item list, item show, repository verify
Your files on disk Yes No

Both hold the complete history, and a copy of either is a bare repository you can check out again. The Synck basics chapter covers everyday work in a checkout. Complete repositories covers reading, copying and checking out repositories without files on disk.

What Synck is not

It helps to be clear about what Synck deliberately leaves to other software:

  • Not a sync service. Synck does not copy changes between your devices in the background. A copy is a point-in-time snapshot that you refresh explicitly.
  • Not an access-control system. Anyone who can read a repository’s files can read all of its retained history, including deleted items. Permissions belong to the application that serves the data.
  • Not the applications. Reading a saved chat does not give you a chat app, and reading saved email does not give you a mail server. Synck preserves the data and its history. The SynckHub applications provide the live services.
  • Not a merge tool. Two diverged copies cannot be combined.

With those ideas in place, install Synck.