Features
Everything DCTL does, and why it does it
DCTL is an rclone-shaped tool with a durability contract bolted to its spine. The vocabulary is familiar; the guarantees are not.
Verified writes, or no write at all
Nothing is reported stored until its bytes are checksum-verified at the destination and durably committed to the local index.
A mismatch hard-aborts the run, deletes the staged object and commits nothing. There are no half-stored files and no false "copied" lines in the log. The contract applies identically to plain and encrypted remotes.
Constant memory, whatever the size
Chunked AEAD and constant-memory multipart keep peak memory flat as the file grows, rather than proportional to it.
Measured under a 512 MiB cap: peak RSS stays flat at 139–144 MiB from a 256 MiB file to a 4 GiB one, in both directions. The pipeline is read → hash → encrypt → checksum → upload → verify → commit, and no stage materialises the whole file. Note the current CLI copy path still refuses files over 1 GiB — lifting that is the next tracked milestone.
Cross-device restore from a password
The backend is authoritative. A fresh machine with only the password rebuilds the entire path map.
dctl index rebuild rescans the backend’s encrypted name records and reconstructs the path→object map, then restores byte-exact. No index backup to lose, no sync service to trust.
A format frozen for twenty years
A dependency-free C99 reference decoder proves the format outlives the tool that wrote it.
On-disk identifiers are brand-neutral and design-frozen. Known-Answer Tests cross-validate the Rust and C decoders byte-for-byte, so a vault written today stays readable with no Rust, no DCTL and no network.
Post-quantum where it counts
The at-rest path is entirely symmetric. Sharing uses an X25519 + ML-KEM-768 hybrid.
Because at-rest encryption is symmetric (Argon2id + XChaCha20-Poly1305), there is no public-key operation at rest for a quantum computer to break. The asymmetric sharing layer wraps recipients with a hybrid KEM for harvest-now, decrypt-later resistance today.
Ranged reads, ready for a mount
Reading a byte window fetches only the AEAD chunks covering it, so seeking into a huge object is cheap.
A 10-byte window into a 96 MiB object costs about 1.9 MiB of peak memory above baseline, against 97.6 MiB for the whole-object read it replaces, and stays flat on a 512 MiB object. This is what a read-only FUSE mount needs; the mount command itself is still a stub and is not usable yet.
Metadata-private encrypted index
Filenames and directory structure never reach the provider in the clear.
A vendored SQLCipher index with three-layer keying — keyed hash, per-row AEAD and whole-database page cipher. WAL mode makes it safely multi-process.
Encryption is optional, never accidental
A remote is plain or vault-wrapped, and what a command encrypts depends only on the remote name you typed.
A destination’s contents can cause DCTL to refuse an operation — never to silently change what it does. Plain rclone-style copy, move and sync are fully supported, and the verified-write contract covers both modes.
The pipeline
Seven stages, and the last two are the point
Reading, hashing, encrypting and uploading are table stakes. Verifying at the destination and committing durably are what let DCTL claim a file is stored.
- readbounded chunks
- hashBLAKE3
- encryptXChaCha20-Poly1305
- checksumciphertext digest
- uploadconstant-memory multipart
- verifycompare at destination
- commitindex says it exists
Command surface
The verbs you already type
Addressing rules, filter syntax and command names follow rclone's conventions on purpose, so the tool disappears and the guarantees stay. Every command has its own reference page in the documentation.
dctl configCreate and manage configuration and remotesdctl initCreate a vault and print its recovery phrase oncedctl copy / copytoCopy files, or a single exact path. Never removes anythingdctl syncMake the destination match the source. Deletesdctl move / movetoCopy, then delete the source once the write is verifieddctl replicateCopy a vault’s ciphertext to a second store. No password neededdctl cat / rcatStream an object to stdout, or stdin into an objectdctl ls / lsl / lsd / lsjson / treeList in five shapes, including machine-readabledctl size / aboutTotals, and what the backend supportsdctl delete / deletefile / purgeRemove objects, a named object, or a whole pathdctl rmdir / rmdirs / mkdir / touchDirectory and placeholder handlingdctl cleanupAbandoned uploads, stale temporary objects, old versionsdctl verify / check / scrubRe-prove what is stored, at three depthsdctl hashsumDigests, for comparing against an external recorddctl index rebuildReconstruct the path map from the backend alonedctl vaultVault maintenance, including password rotationdctl backup / restoreScheduled backup and restoredctl auditRead the hash-chained operation logdctl mountRead-only FUSE mount of a vault — stub, not usable yetdctl version / completionBuild information and shell completions
Architecture
Eight crates, layered so the crypto core stays clean
The layering exists to keep one promise structural rather than aspirational: the crate that touches your keys contains no unsafe code, and the one crate that does is small enough to audit.
dctl-cryptoFrozen v1 format and every primitive. Forbids unsafe code outright.
dctl-secmemThe one audited home for unsafe FFI — mlock, madvise, locked secrets.
dctl-metaSingle renameable source of the app name, paths and env prefix.
dctl-storeProvider-neutral Backend trait, plus LocalFs, B2, S3 and R2.
dctl-indexSQLCipher-encrypted, metadata-private local index.
dctl-coreVault — composes crypto, store and index into one API.
dctl-cliThe dctl binary and its addressing invariants.
dctl-decodeDependency-free C99 reference decoder and KAT cross-validation.
Lineage
Inspired by rclone, implemented from scratch
DCTL is written from scratch in Rust, but its addressing rules, filter syntax and command vocabulary were heavily inspired by the excellent work of the Rclone project. If you know rclone, you already know how to drive DCTL.
| Capability | Rclone | DCTL | Notes |
|---|---|---|---|
| copy / sync / move / ls / cat | Yes | Yes | Same mental model, same filter and addressing rules |
| Breadth of backends | 70+ | Focused set | Local and B2 today; R2, S3, Drive and SFTP on the roadmap |
| Client-side encryption | crypt overlay | Vault with identity | A vault has a vault_id, revocable key slots and an encrypted index — two remotes sharing a password are not interchangeable |
| Verified write before success | Optional checks | Yes | Non-negotiable, on both plain and encrypted remotes |
| Post-quantum sharing | No | Yes | X25519 + ML-KEM-768 hybrid recipient wrap |
| Metadata-private index | No | Yes | Encrypted SQLCipher index; filenames never leave in the clear |
| Format decodable without the tool | No | Yes | Dependency-free C99 reference decoder plus Known-Answer Tests |
| Tamper-evident audit log | No | Yes | Hash-chained, order- and integrity-preserving |
| Licence | MIT, open source | PolyForm, source-available | Free for personal use and for noncommercial organisations; any business use requires a commercial licence |
Free for personal use, and for everyone doing it for the public good.
Under the PolyForm Noncommercial License, personal projects, charities, schools, universities, public research and government bodies get the complete tool at no cost. Business use needs a commercial licence.