Documentación
Licensing and sync
Activating a license and replicating state across devices.
En esta página
Activating a device
A TDE install is standalone until you activate a license on it. Activation is what turns a machine into one of your machines: it registers the device, hands back sync credentials, and lets that device participate in replication and in cross-machine ownership.
tde license activate --key TDE-XXXX-XXXX-XXXX
tde license status--name labels the device; without it TDE uses the previously saved name, then the
system hostname, then a generic fallback. activate prints where it is calling and
where the credentials landed:
Activating "office-vps" against https://www.tde.sh/api …
Activated. Device registered; sync credentials saved to /home/you/.tde/sync/state.jsonRe-running activate with the same key is a no-op and exits 0 without a network
round trip. A bad key exits 1 with invalid or unrecognized license key; a usage
error exits 2. Those exit codes matter because this command is designed to run on
a cloud machine's first boot with no screen attached.
tde license status is purely local and never calls the network:
activated (cloud) — device: office-vpscloud means remote sync credentials are present; local means a license is saved
but no remote block; not activated means neither.
What activation actually does
The device posts its license key, a stable device id, a device name, the platform
and the app version to the TDE License API. The response carries a database URL and
an access token for your private replicated database, plus an optional refresh
interval. TDE then opens that database, saves the license, registers the machine in
the shared machine registry, and writes everything to ~/.tde/sync/state.json.
The device id is derived from the host — /etc/machine-id where it exists,
otherwise a persisted random id created atomically under a lock so that the desktop
and the Runtime converge on the same identity.
The access token is refreshed automatically when it is within 24 hours of expiring; a failed refresh leaves the working token in place rather than logging you out.
What replicates
Sync is not a filesystem mirror. It replicates a specific, curated set of records through your private database.
| Replicated | Notes |
|---|---|
| Board tasks | Title, stage, labels, assignee, project, description, priority, subtasks. |
| Projects | Name, repository URL, default branch, pipeline and integrations — not the local path. |
| Canonical agent sessions | The portable turn timeline. See Resume anywhere. |
| Brain and decisions | Pages, observations, graph edges, embeddings, decision entities. |
| Credential files | Exactly two: the GitHub CLI hosts file and your .gitconfig. |
| Vault secrets | A fixed allowlist of provider API keys, row by row. |
| Machine registry | Presence, platform, app version, and the ownership flags below. |
| Session index | The cross-machine Resume list. |
| Small text attachments | Capped; larger files are skipped. |
| Ownership claims | Bot slot leases and service deployment claims. |
Each machine derives its own filesystem paths. A project's local_path is
deliberately absent from the schema, which is why a new machine clones repositories
rather than inheriting somebody else's directory layout.
Encryption
Credential files, vault secrets and canonical agent sessions are encrypted before they reach the database, with AES-256-GCM-SIV under a key derived from your license key. Every feature uses a distinct salt, and the row name is bound into the derivation, so a blob for one row cannot be decrypted as another and the three registries never share key material.
The key is never stored in the database — it is derived on each device from the
license. Rotating the license changes the key, so older blobs stop decrypting; TDE
treats that as absent rather than fatal and re-pushes from whichever device still
has the plaintext. tde sync hydrate reports it as a note:
note: 3 key(s) could not be decrypted (license rotated?)Presence and conflicts
Every device heartbeats every 20 seconds and is considered online for 75 seconds — deliberately longer than three intervals, so scheduler jitter cannot trigger a false failover. Timestamps come from the server clock, not the device's, and a timestamp from the future fails closed: a machine with a broken clock cannot hold an election after it disappears.
Conflicts resolve last-write-wins on a millisecond timestamp. Deletions are tombstones, never hard deletes, everywhere it matters — tasks, projects, secrets, agent sessions, Brain pages. A hard delete only removes a record locally, and the next pull resurrects it on every device.
Credential pulls have an extra guard: a remote blob that looks logged-out is never written over a real local file, and a remote blob only overwrites a local file when it is genuinely newer.
Hydrating a new machine
tde sync hydrate is the "make this box useful" command. It is designed to run
unattended on a cloud machine's first boot, right after activation.
tde sync hydrate
tde sync hydrate --credentials-only
tde sync hydrate --repos-onlyIt runs three phases:
| Phase | What it does |
|---|---|
| Credential files | Writes the replicated GitHub CLI and git config files, owner-only. |
| Vault API keys | Merges replicated provider keys into the local secret vault. |
| Project clones | Clones every replicated project that is not already on disk. |
--credentials-only runs the first two — the point is to get the box able to talk
to GitHub and to a model provider before cloning anything. --repos-only runs only
the third. The flags are mutually exclusive.
Cloning is careful: destination is TDE's managed repositories directory, existing
checkouts are skipped, the default branch comes from the replicated project record,
and if the GitHub CLI is authenticated and the URL is a GitHub one, TDE clones
through gh so private repositories inherit the credentials it just hydrated.
Clones are bounded in time, a partial checkout is removed on failure, and an
individual failure is reported and skipped rather than aborting the run.
Activation is a hard precondition. Without it, hydrate exits 1 and tells you to
run tde license activate first.
Ownership across machines
Multiple devices on one license must not all do the same work. Three independent mechanisms enforce single ownership, and they behave differently — do not conflate them.
The elected Bot host. One flag on one machine. The first device claims it; the heartbeat re-elects deterministically — the earliest-registered online device — whenever the current host disappears from the presence window. Assistant and Slack processing has its own, independent host flag with the same rules.
Fenced Bot slot leases. Each cron slot is claimed with a 90-second lease carrying a monotonic fencing generation, renewed on the 20-second tick. Expiry takeover bumps the generation, so a stalled executor can neither renew nor commit a result afterwards. The claim is scoped by a hash of the license, never the raw key.
Service deployment claims, keyed by license, project and service. These are insert-first under a unique key inside a transaction, so two machines racing cannot both win. They have no TTL — a claim does not lapse because a laptop went to sleep. The owner releases it when the service is removed; removing that machine from the licensed fleet makes the claim reclaimable. There is no automatic destructive handoff.
Related
- System commands — the rest of
tde licenseandtde syncin the CLI reference. - Secret vault — where credentials live locally.
- Machines — cloud desktops that activate and hydrate on boot.
- Pricing — which plans include sync.