kane-cli context sync shares your .context/ store with your team through a location: a GitHub repository, an S3-compatible bucket, or a folder on a shared drive. Each person keeps their own store on their own machine, and the location holds the history the team shares.
kane-cli context pushpublishes your new records to the location.kane-cli context pulltakes your teammates’ new records from it.kane-cli context clonecreates a new store from the location.
Requires Kane CLI 0.8.14 or later.
kane-cli context ingest <file> --mode ci creates one from a first document; see Building the context graph. Then run:
Three kinds of location
GitHub
- Use a dedicated repository, not your code repository, and make it private if your requirements are private.
- Git 2.31 or newer must be installed on the machine.
- Connection check. Setup and
kane-cli context sync addtest the repository by writing a few small, permanent connection-check files and commits. They never publish your context. The check also pushes to a scratch reference underrefs/kane/probe/. If the check cannot finish (SYNC_PROBE_INCONCLUSIVE), the usual cause is a repository rule that blocks that reference: ask the repository owner to allow it, then run the command again. - How pushes land. Each push is one ordinary commit on the branch. Nothing is force-pushed, merged, or rebased on the server.
- Size limit. GitHub does not accept a single object larger than 100 MB. If a source document is larger than that, use an S3-compatible bucket instead.
- Signing in over HTTPS. If you have no stored login, the GitHub CLI sets one up in two commands:
gh auth login --hostname github.com --git-protocol https --web, thengh auth setup-git --hostname github.com.
S3-compatible storage
Ask your storage administrator for an existing bucket and a key pair. Kane CLI does not create either one.- Passing the keys.
--credential-env TEAM_S3readsTEAM_S3_IDandTEAM_S3_SECRET.--credential-file keys.jsonreads{"accessKeyId": "…", "secretAccessKey": "…"}. - Where the keys are saved. Either way, the pair is saved in
~/.testmuai/kaneai/context-sync/<name>.json, readable only by you (mode0600).kane-cli context sync remove <name>deletes it. - Keys belong to the location’s name. The file is tied to the location’s name, not to one store. Every store on this machine whose location is called
originreads the sameorigin.json, so binding a second bucket asoriginfrom another store replaces the keys the first store uses. If one machine works with more than one bucket, give each its own name (team-s3,archive). - Keys from the environment (CI). When
KANE_SYNC_S3_ACCESS_KEY_IDandKANE_SYNC_S3_SECRET_ACCESS_KEYare both set, they take priority over the file and are never written to disk. Use this form in CI. - A refused key pair never replaces a working one.
Folder
A mounted shared drive works for a team. A path on your own disk works only for you, because sharing the path does not share its contents. If the folder does not exist yet,kane-cli context sync add creates it, as long as its parent folder exists.
Guided setup
TTY_REQUIRED and points you to kane-cli context sync add and kane-cli context clone instead. Setup never publishes your context; publishing is always a separate kane-cli context push.
The first screen asks What do you want to do? with two choices: Share my context with my team or Join my team’s context.
Share
Setup asks where the shared context should live: GitHub — Recommended, S3-compatible storage, or Folder. It then asks for the details of that kind:- GitHub: the address of an existing repository. Or choose the row that opens GitHub in your browser, create a dedicated repository there, and come back with its address. If Git or the GitHub CLI is missing, you see an installation link and a row to retry.
- S3: the bucket name; the region (prefilled with
us-east-1); an optional folder inside the bucket; the service (Amazon S3, or another S3-compatible service, which then asks for its endpoint); and how to connect. You can use credentials already configured on this computer, or type in the access keys from your storage administrator. The secret access key is masked as you type, and the keys are saved in your local Kane CLI credential store, never in the shared context. - Folder: the path. The screen reminds you that everyone needs the same mounted drive.
origin. If this store already has a location called origin, setup asks for another name and suggests team.
The last screen shows the address and tells you that the connection check adds small, permanent files to the location (and, for a repository, commits). It then waits for you to choose Connect location. After connecting, setup tells you whether you can publish:
- With write access, it shows the
kane-cli context push <name>line to run when you are ready. - Without write access, it asks you to get write access and check the connection again.
Share this location with teammates: followed by the complete address (for a Git location, the repository address with the branch and prefix you chose), and one closing line saying who can read it.
If the location refuses the connection, Use a different address takes you back through the same prompts with what you typed kept, and Choose a different storage returns you to the storage picker. Press Esc or Ctrl+C to leave setup with exit 3: Setup left. Your context has not been published. Any completed connection checks remain in the location.
Join
- Setup asks you to Paste the location your teammate shared.
- Under Download into a new folder, it asks for a folder (prefilled with
team-context). A folder that already exists is refused, so none of your files is replaced. - Choose Connect and download. Setup downloads the verified team context into that folder and closes with
Next: open that folder and run kane-cli context sync status.
kane-cli context clone <address> <dir>, run by hand, is less strict about the folder. It accepts a folder that already exists as long as <dir>/.context is not there yet, which is how the CI recipe clones into ..
The commands
Two terms appear in the output of these commands:- Witness: the last record this machine saw on a location. Kane CLI keeps it to detect a location that has been rolled back.
- Tier: what the connection checks proved about a location. Tier 1 can publish; tiers 2 and 3 can only be downloaded from. The tier table below explains each one.
If you leave out
[name], the command uses the only location. If there are several, it uses the one called origin. Otherwise it asks you to name one. Every command takes --mode agent for an NDJSON stream; see Agents and CI.
What the tier means
Before binding a location,kane-cli context sync add and kane-cli context clone check two things: that the location can be read, and whether a small test write lands there and reads back. The result is reported as a tier:
kane-cli context sync addprintsadded <name>: <kind> tier <n> (<what the checks found>).kane-cli context cloneprintsbound origin: …in the same format.- Each line of
kane-cli context sync listrepeats the kind and tier.
Joining an S3-compatible location
To clone an S3-compatible location with keys from the environment:The everyday loop
In this example, Alice shares a store she already built and Bob joins it. Then each of them works, pulls, and pushes. Normally Alice and Bob would be on two machines; here they are two folders side by side, with the location as a third:alice/, Bob in bob-home/, and, once the clone exists, inside bob/.
position 2 is the second record of the shared history, which this page calls record 2:
kane-cli context sync origin at both ends.
If a teammate has pushed since you last pulled, any command that writes to the store first prints one advisory line and then continues:
origin has moved past this machine — run kane-cli context pull originwhen only the location moved.this store and origin have diverged — run kane-cli context pull origin --rebasewhen both sides moved.
--mode agent; there, kane-cli context extract, kane-cli design tests and kane-cli maintain reconcile emit a sync_behind event instead. kane-cli context review prints it unless you pass --json or --mode agent, and a test run writes it to its session log. Set KANE_SYNC_GUARD=0 to turn it off.
Ingest, extract, review, and design all work as usual. The location only changes where the records go afterwards. What a push sends, and what stays on your machine, is listed in What travels.
What travels and what never travels
The sync commands never call the agent, so publishing, taking, cloning, and rebasing cost no credits. A store that pulls a use-case gets the same records the extraction committed, including the cited lines.
When a command refuses
Every sync refusal prints a plain-language reason, and nearly all add anext: line with the command to run. On the agent stream, the same refusal is a sync_error event with a stable code, the reason, and the fix. The most common refusals are:
Exit codes:
3: a person has to decide something.2: a precondition is not met.1: a record cannot be used.
kane-cli context sync finishes its pull before its push can be refused, and a push can land before its confirmation is lost. A refusal not listed in this table still tells you what stopped and what to run next. How an agent handles these codes is in Agents and CI, and the entries a person meets most are in Troubleshooting.
When two people changed the same thing
Here is an example. Alice and Bob both worked after the same shared record (record 2):- Bob named the source
brief“spec”, ingested a new version ofprd, then pushed. - Alice, without pulling, named
prd“spec” and retiredprd.
kane-cli context sync status origin says you and origin both added work after position 2 and names the command to run. kane-cli context push origin refuses with the same words (exit 3), and so does a plain pull.
kane-cli context pull origin --rebase resolves this in three steps:
- It saves Alice’s records that come after the shared record in a backup.
- It takes origin’s records.
- It reapplies the saved records on top, one by one.
kane-cli context pull origin --rebase --yes. --yes confirms only the rebase itself; it never answers a decision. Choosing Not now prints no rebase started — run kane-cli context pull origin --rebase when you are ready and exits 3, with nothing saved or taken.
Most saved records reapply without a question, with one line each. A record the other side did not touch is reapplied, and a record the other side already made the same way is skipped as already there. A real disagreement about one thing comes to you as a decision card, one at a time. The two sides are always called local and the location’s name:
by is the author id recorded with that change: a person’s user name as their machine reported it, or an agent. someone means the record has no author, as with a re-ingested source.
The answers on a card:
- Keep origin’s version is always offered and is always the default. It writes nothing, and the local change stays in the backup.
- Apply the local version writes the local change as a new record on top of origin’s. The row tells you the consequence.
- Add the local version as new replaces apply the local version when the item is newly created and origin has since retired its match. It creates a new node beside origin’s (duplicate check first).
- Decide later leaves the card open, and
kane-cli context syncorkane-cli context pullasks again.
v to show the full record under the facts, a to leave every remaining card for later, or Ctrl+C to pause. None of these is an error. Each answered card leaves one line in the scrollback (decision h3: kept origin's version), and the run ends with a summary that counts what was reapplied, already there, not reapplied, and undecided.
Some saved records cannot be reapplied at all, and their card offers only keep origin’s version. This happens with a record this version of Kane CLI cannot read or replay, a record that refers to an item origin no longer has, or a record the store’s own checks refuse. The change stays in the backup, and you need to redo that piece of work after the rebase is finished. Keeping origin’s version can also bring back a later card, because any saved record built on the one you set aside is checked again.
Without a terminal (a pipe, CI, or --mode agent), no card is shown. Each open decision is one line with its id, the kind of record, the local change in words, and the answers it accepts. kane-cli context sync status repeats them. If the location cannot be reached, the human-readable output still lists them before the refusal, and --show <n> works without the location:
kane-cli context sync status --show <n> prints saved record n in full: what it did, what origin holds instead, the answers it accepts, and the raw detail behind the card.
origin sha256:…, is the saved record’s own hash: the word there means the original record, not the location, and the location’s side is the origin: row below it.
To answer by id, pass --answer <id>=<choice> to kane-cli context sync or kane-cli context pull:
keep-theirskeeps origin’s version.apply-mineapplies the local version.apply-mine-as-newadds the local version as new.
not synced: 1 decision waiting — run kane-cli context sync origin to answer it, or kane-cli context sync origin --answer h4=<choice>). The last answer finishes the rebase. After that, kane-cli context sync pulls and pushes as usual, while kane-cli context pull only pulls. In this example, --answer h3=keep-theirs was given in the previous run:
kane-cli context sync status --show <n> names the record it became:
kane-cli context push refuses with the same code and the same next: line. Its reason names the rebase, counts the unresolved decisions, and says nothing was pushed. A test run does not refuse: the results it records are set aside and land on the first run after the rebase is finished.
kane-cli context sync doctor shows the store’s state and every rebase with its id, open or closed. Three terms in its output come from how a rebase works internally:
- A rebase id ends in
-reset. - The first line,
no reset in progress, refers to the import step of a rebase. It readsreset in progressonly when an import was interrupted before it finished. sentinel: absentis the healthy state. The sentinel is the marker a running import leaves in the store.
kane-cli context sync doctor --abort closes the open rebase. It keeps what was already reapplied and leaves the unanswered decisions in the backup (exit 3 when decisions were left). From another run, with one decision open:
kane-cli context sync doctor --abort undoes it: your records are put back and the store returns to how it was. Once the import has landed, the rebase can only be finished (SYNC_RESET_IMPORTED). kane-cli context sync or kane-cli context pull finishes it before doing anything else, and you can then close it with kane-cli context sync doctor --abort if you still want to.
Getting back the store as it was. The live store holds records your teammates published, so it is never rewound in place. Instead, kane-cli context sync doctor --export <dir> rebuilds your store as it was before the rebase in a separate folder, as its own store. Use it to inspect the old state or as a fresh start:
kane-cli context list or kane-cli context explain. It has no location bound, so run kane-cli context sync add there first if you want to share from it.
Without --from <rebase-id>, the export uses the open rebase, or the only one. If there are several closed rebases, name one. Everything a rebase saves stays under .context/sync/backups/<rebase id>/ and .context/sync/replay/, where a receipt lists every reapplied, skipped, and undecided record.
A _test.md file created by a reapplied record is restored, and the summary’s test files … restored line counts these files. If someone else’s file is now at that path, Kane CLI leaves it alone and kane-cli context sync status lists it. Rename or move that file, then run kane-cli context sync again.
What happens when
origin is the location, and local means the records saved from your store.
For agents and CI
Every sync command in the table above takes--mode agent and emits NDJSON events: sync_status, sync_pull_done, sync_push_done, the sync_rebase_* events, sync_error{code, detail, remedy}, and done last. A rebase that stops on decisions ends with done carrying paused, and exit 3. Agents and CI describes the events in full, and CI/CD has the CI setup with a GitHub token or deploy key.
FAQ
Can I merge two stores that were never connected? No. A location holds one history, and a store started separately isa different history. Instead, clone one of them and ingest the other’s documents into it again.
Next Steps
- Building the context graph for ingest, extract and review
- Agents and CI for the headless contract, including the sync verbs
- Configuration for the sync environment variables and on-disk paths
- Troubleshooting for the sync entries