When you develop by running multiple sandboxes simultaneously, it’s convenient that each environment is isolated, but it can become unclear what the other sandboxes are doing.
For example, suppose you conduct research and decide on a design approach in one sandbox, then begin implementation in another. The new sandbox has no prior conversation, so you don’t know why that approach was chosen or what issues remain unresolved. As a result, you may end up repeating the same research or re‑examining decisions that have already been made. It can also happen that one worker unintentionally edits a file another worker is working on, causing their work to clash.
Since conversation history isn’t shared between sandboxes, someone has to re‑explain the background each time. However, copying the entire conversation is cumbersome, making it hard for the next worker to locate the information they need.
Therefore, we decided to limit the shared information to development context rather than the full conversation. If the next worker knows the decisions made, the current tasks, the files that have been changed, and any notes for the next person, the new sandbox can start from the same assumptions. To realize this, we created the CLI tool ctx-sync .
Idea: Share the facts needed for work, not the conversation
Initially, we didn’t intend to simply pass the conversation to another sandbox. Conversations contain a lot of trial‑and‑error, temporary hypotheses, debug logs, and the like. Syncing all of that would be burdensome for a new worker to read, and it would mix in information that doesn’t need to be shared.
We divided the shared information into three layers.
| Shared Information | Example |
|---|---|
| Project | Purpose, current architecture, design decisions already adopted |
| Coordination | Worker status, tasks being performed, changed files, hand‑off items |
| Local | Conversation, reasoning, ideas only tried, temporary debug notes |
What we share are “why this design was chosen,” “how far the work has progressed,” and “what the next person should be aware of.” The reasoning steps and conversation logs themselves remain local to each sandbox, leaving only the facts necessary for other workers to act.
Implementation: Using GitHub Gist as a Git Repository
Where should this shared state be stored? If we put everything into the project’s Git repository, each worker’s temporary progress would be mixed with the regular source code. Setting up a dedicated server would require authentication and ongoing maintenance.
Therefore, we decided to use GitHub Gist as the shared location. Because a Gist can be cloned as a Git repository, we can synchronize from multiple machines or sandboxes without provisioning a special server, using existing Git credentials.
ctx-sync is a Rust‑based CLI tool, and the project side includes a .ctx-sync.toml that identifies the Gist. Local clones and worker identities are stored outside the project directory; by default, it uses macOS’s Application Support folder or Linux’s ~/.local/state/ctx-sync.
The Gist has the following file structure.
00-meta.json
10-project.md
20-architecture.md
30-decision-<date>-<number>-<slug>.md
40-worker-<short-id>.md
Design decisions are stored in separate files, one per decision; instead of overwriting older decisions, new ones are added to replace them. Each worker updates only their own 40-worker-*.md. This separation makes it less likely for one worker’s work state to overwrite another’s, even when multiple workers are progressing simultaneously.
Starting Work and Hand‑off
When beginning work in a sandbox, run ctx-sync agent start.
ctx-sync agent start
-> If necessary, attach this checkout to a Gist
-> Register worker identity
-> Pull the latest shared context
-> Display architecture, decisions, active workers, and notes
For a new project, first create a Gist and register the worker.
ctx-sync init --project example --create-gist --secret
ctx-sync register sandbox-a
ctx-sync agent start
If you commit the generated .ctx-sync.toml to the project, other worktrees or sandboxes can locate the same Gist. Participants can simply perform a fresh checkout and run ctx-sync agent start --name sandbox-b.
When you finish work, record in the worker’s hand‑off what changes were made, which files are important, and any unresolved issues.
ctx-sync agent finish --summary "Add configuration loading" \
--attention "CLI compatibility tests have not run"
When the next sandbox runs agent start, it first pulls the latest context and then receives the onboarding information. Instead of each worker writing a long hand‑off note and pasting it into the conversation, the process updates the shared state in a standardized format.
When adding to an existing project, you can gather candidate shared items from the repository with ctx-sync bootstrap. Even after running --apply, the content isn’t synced to the Gist immediately; it is first written locally to the shared document. Once a human reviews the content, it is published with ctx-sync sync.
Simultaneous Updates Are Not Automatically Overwritten
Since multiple sandboxes may update the same Gist, conflicts can occur.
ctx-sync’s synchronization performs a Git fetch, rebase, and push. If another worker has already pushed, it first rebases and then attempts a push. If, between fetch and push, the Gist is updated again and becomes a non‑fast‑forward, it will retry up to three times.
If the same file is edited independently by different workers and a rebase conflict occurs, ctx-sync does not automatically choose one side. It aborts the rebase, shows the conflicting files, and stops, leaving a human to resolve the conflict. Because the shared context is used for subsequent decision‑making, we preferred to make the conflict visible rather than silently overwrite the content.
Having each worker own separate files is not a mechanism to eliminate conflicts entirely. Instead, it partitions the work into units that can be updated independently, making it easier to identify exactly where conflicts arise when they do occur.
Not Everything Is Shared
Even if the Gist is created as a secret, anyone who knows the URL can read it. It is not a place to store authentication credentials or API tokens.
handoff and decision add issue warnings for strings that clearly look like credentials—such as sk-, ghp_, github_pat_, or private‑key headers. However, this is merely pattern detection and does not guarantee that all secret information will be found. The content must be reviewed before sharing.
Therefore, ctx-sync synchronizes only the short facts needed for the work. Instead of pasting entire debug logs or conversations, it condenses the information into a form useful for the next steps, such as “this error has been reproduced,” “this file is being edited by another worker,” or “this design decision has been adopted.”
Not an Orchestrator
ctx-sync is not a tool that launches workers, assigns tasks, or determines the order in which sandboxes run. It also does not collect and monitor all workers’ conversations.
What it does is synchronize the shared context via Git and read/write each worker’s state. For Codex, we also provide a skill that reads the shared state at the start of work, records design decisions, and writes a hand‑off at the end. There is also a command to append sharing rules to the project’s AGENTS.md, allowing you to review the additions before committing without overwriting existing instructions.
When multiple sandboxes run simultaneously, ensuring that each worker can start from the same assumptions is more important than sharing conversation history. Rather than syncing the entire conversation, we chose to capture only the facts needed for the work and synchronize them via Gist and Git. ctx-sync was created as a lightweight shared notebook for this purpose. Start by using it to synchronize decisions and hand‑offs.