CodeFolderSync V3 recursively synchronizes an included Code folder across trusted machines. It discovers ordinary directories and Git repositories at any depth, uses a self-hosted local or SSH hub, and has no account or hosted control plane.
Architecture, protocol, safety, operations, and maintainer documentation is indexed in docs/README.md.
V3 is incompatible with V1 and V2. It uses schema and protocol version 3, a fresh folder ID, a fresh hub, signed configuration, new state, and a source-authoritative adoption workflow for populated targets.
- The initial authority seals one checkpoint. Targets cannot publish during adoption.
- Target-only and divergent data moves to target-local
adoption-recoverybefore canonical materialization. - Adoption never applies target state to the authority root.
- Normal concurrent writes use the accepted hub checkpoint as the canonical side and preserve the other complete version under a
CODEFOLDERSYNC-CONFLICTpath. - File objects, manifests, event history, conflicts, and recovery are retained. Garbage collection is report-only.
- Symlinks synchronize target text and are never followed.
- Git metadata remains local. The signed policy selects default-branch working files or an explicit file allowlist. Default-branch transfer requires matching branch and HEAD; external Git directories stop setup or synchronization. The new policy contract is in development and its remaining acceptance gates must pass before daily-driver activation.
.codefoldersyncand.workspace-syncare hard exclusions.node_modulesis excluded by the generated default contract.
CodeFolderSync requires Node.js 22 or newer. Download the release archive and checksum from GitHub Releases, verify them, extract the archive, then run:
python3 codefoldersync-0.3.0/scripts/install.py --release-sha256 <archive-sha256>
codefoldersync --version
codefoldersync --version --jsonThe release installer is idempotent and supports --verify --json. It installs a versioned build under ~/.local/lib/codefoldersync and activates ~/.local/bin/codefoldersync without requiring a repository checkout.
Git is required for synchronized Git boundaries, and SSH is required for a remote hub. For development, pnpm builds and installs the current checkout:
corepack pnpm install
pnpm check
pnpm build
node dist/product-cli.js install --release-sha256 <accepted-release-sha256>
~/.local/bin/codefoldersync --versionThe installer copies the build to ~/.local/lib/codefoldersync/0.3.0/ and atomically activates ~/.local/bin/codefoldersync. The wrapper records the absolute Node executable used during installation, so launchd/systemd and noninteractive shells do not depend on nvm or shell startup files. Install the same exact build on every peer and the hub host.
Interactive setup prompts for the authority and every populated target, requires a verified encrypted-backup witness ID and final approval, performs enrollment and adoption, and stops before cutover with services disabled:
codefoldersync setupThe authority-only primitive remains available for staged or distributed operation:
codefoldersync setup \
--mode authority \
--root /absolute/path/to/Code \
--hub /absolute/path/to/new-hub \
--backup-witness <verified-witness-id> \
--peer mattbookSetup creates authority-controlled files below each selected root:
.codefoldersyncignore
.codefoldersync/config.json
.codefoldersync/authority.json
.codefoldersync/README.txt
Runtime state lives outside the synchronized namespace and must share its filesystem with the root. The interactive wizard defaults to a hidden sibling of each root; authority-only setup defaults to ~/.local/state/codefoldersync/<folder-id>/ and rejects it when it is on a different filesystem.
For a controller that can see every isolated root, the same complete populated-fleet ceremony is scriptable:
codefoldersync setup --mode fleet --spec /path/to/fleet-setup.json --approveThe JSON spec names the folder, verified backup witness, local or SSH hub, authority root/state/config, and each target root/state/config/request path. Interactive and scriptable setup create target-local keys, enroll and project the final signed adoption revision, seal the source, adopt each populated target, force-verify them, and stop with services disabled. They never perform cutover. Remote machines must first have the exact build, verified SSH route, credentials, and roots made available by the external fleet ceremony.
For isolated machines, the distributed controller verifies the exact recorded release on every endpoint and previews without mutation:
codefoldersync setup --mode distributed --spec /path/to/distributed.json
codefoldersync setup --mode distributed --spec /path/to/distributed.json --approve-prepare
codefoldersync setup --mode distributed --spec /path/to/distributed.json --approve-target wootbook --adoption-id <id>Preparation journals authority creation, target-local enrollment, accepted projections, source seal, and deterministic adoption-plan IDs. It stops before target mutation. Each target apply needs its own machine ID and exact adoption ID. A lost response resumes the same operation instead of creating another identity or plan.
Each target generates its own peer key and a signed enrollment request. No private key leaves that target state directory.
codefoldersync setup \
--mode request \
--accepted-config /path/to/accepted-authority-config.json \
--root /absolute/target/Code \
--state /absolute/target/state \
--peer wootbook \
--request /absolute/path/wootbook-request.jsonThe authority reviews and enrolls it:
codefoldersync setup \
--mode enroll \
--config /authority/Code/.codefoldersync/config.json \
--request /path/wootbook-request.jsonProject the resulting accepted revision back to the target:
codefoldersync setup \
--mode activate \
--accepted-config /path/to/latest-accepted-config.json \
--state /absolute/target/state \
--request /path/wootbook-request.jsonRepeat enrollment for every target before sealing the source, then distribute the latest accepted revision to all peers.
codefoldersync adoption seal --config /authority/config.json
codefoldersync adoption plan --config /target/config.json
codefoldersync adoption apply --adoption-id <id> --config /target/config.json
codefoldersync adoption verify --config /target/config.jsonplan does not mutate the target tree. apply revalidates the approved target digest, preserves conflicts out of root, materializes the included seal, force-hashes the result, and records the target as verified. Git metadata stays local; the default-branch policy also verifies each eligible repository's identity, branch, and HEAD.
After every enrolled target verifies, cutover requires an explicit approval flag:
codefoldersync adoption cutover --approve --config /authority/config.jsonThe signed barrier advances the hub to normal mode. It does not start services. Project the new accepted revision to every target and start services one at a time only after the intended operational approval.
codefoldersync doctor
codefoldersync status
codefoldersync sync
codefoldersync verify --full
codefoldersync config status
codefoldersync catalog status
codefoldersync conflicts
codefoldersync historyThe catalog is derived. V3 has no repository or folder membership mutation commands.
Services install disabled unless --activate is explicitly supplied, and cannot start before cutover:
codefoldersync service install
codefoldersync service start
codefoldersync service status
codefoldersync service logsRecover retained adoption evidence to an absent path without deleting the retained original:
codefoldersync recover <conflict-id> --to /absolute/absent/pathThe authority-controlled root file uses deterministic Git-ignore-style rules with anchoring, directory rules, **, comments, blank lines, and negation. The generated minimum is:
/.codefoldersync/
/.workspace-sync/
**/node_modules/V3 does not reuse .gitignore. A target whose ignore digest differs from the accepted configuration fails closed.
On the authority, preserve the previously accepted ignore file, edit the live file, preview its path/byte delta, then approve a signed revision:
codefoldersync config update-ignore --previous-ignore /path/to/previous.ignore
codefoldersync config update-ignore --previous-ignore /path/to/previous.ignore --approveProject the accepted revision and exact ignore file to every peer before synchronization resumes.
pnpm check
pnpm buildThe focused V3 integration suite uses fresh temporary roots. It covers two populated target adoptions, recovery evidence, exact source immutability, source-seal/adoption/normal-apply/cutover interruption recovery, physical and contained-indirection Git convergence, signed cutover, atomic snapshot/conflict publication, recursive normal synchronization, immutable directory conflicts, rename cycles, keep-both conflicts, metadata-only directory moves, corrupt-object rejection, reserved and ignored paths, configuration/ignore tamper rejection, portable-name collisions, special filesystem objects, and external Git-dir rejection. It never targets a daily-driver Code folder or service.