Publishing a repository
The operator flow — create a repository handle, dry-run the snapshot, publish it signed, and verify what readers will see.
This page is for people running their own workspace or using the API. If you use a workspace created at syncropel.com, start with Your hosted workspace.
This is the hands-on companion to the repositories concept: the four steps from "records on my instance" to "a signed publication anyone can read."
1. Create the handle
spl repo create acme/product-notesThe slash name is both the identity and the URL path. The namespace half
(acme) is derived from the name; pass --namespace to override when the
repository should live under a different one you own. Duplicate names are
rejected.
Check what exists:
spl repo list
spl repo show acme/product-notes2. Dry-run the snapshot
spl repo publish acme/product-notes --dry-runThe dry run builds and stages the full publish tree locally — nothing uploads, nothing becomes visible. Use it to see exactly what a publish would contain before the first real one, and as a pre-flight in scripts.
3. Publish
spl repo publish acme/product-notesPublishing runs server-side on your instance and is owner-gated — only the identity that owns the namespace can publish under it. The command snapshots the repository's records, signs the snapshot and its listing with your identity, and uploads to published storage.
Useful flags:
| Flag | What it does |
|---|---|
--visibility public | Full detail (the default). Reduced-detail levels publish structure over content — see the Graph. |
--topic <topic> | Advertise a topic on the listing (repeatable) so readers can find the repository by subject. |
--dry-run | Stage locally, upload nothing. |
--json | Machine-readable output for scripts. |
Re-running publish advances the published state — each run is a fresh
signed snapshot; readers always see the latest complete one.
Keep it published automatically
You don't have to re-publish by hand. Publishing with --relocation
snapshots the whole instance as its portable form ("backup = publish"),
and once a home is bound to a published repository the daemon's
continuous write-back flushes new records to the published tree as
they land — the publication follows your instance instead of trailing
it. See Backup & restore for the
recovery half of the same story.
A hosted workspace keeps its own repository
A hosted workspace can hold its repository from the moment it is created, with no key of its own to manage. Three doors do it, each an owner action.
- Declare the handle:
POST /v1/repo/declarewith{"name": "notes"}. The handle is<your workspace's label>/notes. Declaring the same handle again answerscreated: false; a different repository under that name is409 REPO_EXISTS. - Publish it:
POST /v1/repo/publishwith{"repo": "<label>/notes", "scope": "instance", "visibility": "L3", "no_listing": true}keeps a private, restorable copy of the whole workspace. With no stored key, the hosting service issues the workspace a short-lived key for its own repository. Before it writes, it takes the repository's write lease, so no second writer can move the published state under a live one. A workspace with no repository bound yet is bound to what it just published, and the answer saysbound: true, restart_required: true: continuous write-back starts at the next start. - Bind (for an existing, empty published tree):
POST /v1/repo/bindwith{"repo": "<label>/notes"}. A tree that already holds records is refusedTREE_NOT_EMPTY, because only a restore or a publish knows where to resume.
Refusals a caller can meet, each by name:
| Code | What it means |
|---|---|
LEASE_HELD | Another workspace is writing this repository right now; the message names it and when its lease expires. |
WRITER_IS_LIVE | This workspace already writes back to this repository; its own flush is the publish. |
LOCATOR_NOT_HOME | A bind named a location other than where the repository lives. |
NAMESPACE_NOT_OWNED | A declare named a namespace other than this workspace's label. |
MINT_REFUSED / MINT_UNAVAILABLE | The hosting service would not, or could not, issue the key. |
A standby that finds the lease held takes over by itself once the lease is released or expires, and a clean stop drains one last flush and hands the lease on, so moving a repository's writer does not wait on anyone.
4. Verify as a reader would
spl repo show acme/product-notesThen open the public page:
https://graph.syncropel.com/acme/product-notesCheck the overview renders, the records tab shows what you intended to share, and nothing you meant to keep private is present — the published snapshot is exactly what a stranger sees, so review it as one.
Reading it back: clone, mount, fork
A published repository is not just a page — it is a complete, verified copy other machines can attach to:
# A fresh home from a publication — the `git clone` equivalent.
spl repo clone syncropel://acme/product-notes
# Pull ONLY what changed since the last hydration (incremental).
spl repo mount syncropel://acme/product-notes
# A new branch as one pointer write — segments are shared, nothing is copied.
spl repo fork acme/product-notes experimentsThe locator is a connection string (syncropel://{ns}/{repo}), an HTTPS
base URL, or a local directory. clone and mount run client-side
against a home whose daemon is not running — they verify every segment
hash and record content-address before ingesting, then the daemon
re-folds at next boot. mount on an already-bound home pulls only the
segments past its watermark, so a routine sync is cheap.
To check how far a live instance has drifted from its publication without changing anything:
spl repo drift acme/product-notesExit 0 means aligned, 3 means drift (the output shows which side has
what the other lacks).
Deploy keys — scoped access without your identity
For CI jobs, viewers, or another instance that should read (or write) one repository without holding your identity:
spl repo key acme/product-notes --scope readThe command is owner-gated and prints the bearer once — store it in
your secret manager. The key carries a grant scoped to exactly
repo:acme/product-notes:read (or read-write, which also allows
publish and fork); it opens nothing else on the instance. Add
--expires-days for a bounded lifetime, and revoke at any time with
spl token revoke.
Unlisting — retract discovery, keep the data
spl repo unlist acme/product-notesUnlisting retracts the repository's directory listing — it stops being discoverable — while the published tree itself stays in storage for anyone who already holds the locator or a deploy key. It removes discovery, not data. Owner-gated; re-publishing with a listing makes it discoverable again.
Keeping it saved
Once a workspace is bound to its repository it saves continuously, and it keeps saving through restarts, stops and sleep without anyone acting:
- It retries on its own. If the key is refused or the storage cannot be reached, for example in the first seconds after waking, the workspace tries again with a backoff of at most a minute.
- It says when it is not saving.
/healthand the workspace read carryattach(starting,holding,standing_byorrefused),attach_fact(the reason) andnot_replicating_secs(how long nothing has been saved).spl doctorfails a workspace that is refused and names the reason and the seconds. - It hands the repository on cleanly. A workspace that loses the lease to another one stops counting as the writer at once, including for scheduled work.
The repository keeps your workspace's records: threads, messages, decisions, definitions and
configuration. Files you store in a workspace are not saved to its repository yet, and publish and
restore say so with files_carried: false.
A saved copy can lag the workspace by at most one flush interval (30 seconds on the free plan), so a workspace that is killed outright can lose up to that much of its newest work.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
duplicate name on create | The handle already exists on this instance. | spl repo list to see it; pick another name or publish the existing one. |
| Publish rejected as not owner | Your current identity doesn't own the namespace in the handle. | spl identity show to confirm who you are; create the handle under a namespace you own. |
| Published page missing recent records | Readers see the last snapshot, not your live instance. | Run spl repo publish again to advance the published state. |
See also
- Repositories — the concept
- The Graph — how published work is read
- Namespaces — ownership and the
{ns}/half of the handle
Sharing a thread for bug repro
spl share bundles a thread (with consent) into a single command a recipient can replay against their own instance. Built in, signature-verified, time-bounded.
Authentication & Service Accounts
Enable bearer-token authentication, create service accounts, pair devices, and manage token lifecycle. Bearer-token auth is enforced by default on every spl serve instance.