Settings
Two layers: settings that apply to the whole process, and configuration that applies to one repo. The process layer is read through Object::Configure, so a file, a universal section and environment variables can each contribute; the repo layer is plain JSON written by the tools.
On this page
Process settings
The settings file is ~/.conf/app-filesync.json when it exists,
or the path in FILESYNC_SETTINGS. The section key is
App__FileSync, and a UNIVERSAL section in the same
directory applies to every class that uses Object::Configure. Environment
variables named App__FileSync__KEY override the file.
# ~/.conf/app-filesync.json
{ "App__FileSync": {
"log_level" : "debug",
"log_format" : "%level%: %message%",
"log_file" : "/home/foo/.filesync/filesync.log",
"ssh_identity" : "~/.ssh/filesync_ed25519",
"ssh_known_hosts" : "~/.ssh/filesync_known_hosts",
"server_command" : "/usr/local/bin/filesync-server"
} }
# or, for one run
export App__FileSync__log_level=debug
| Key | Default | Meaning |
|---|---|---|
log_level |
warning |
One of trace, debug, info,
notice, warning, error,
critical, alert, emergency
(and the usual short spellings). An unknown level is an error. |
log_format |
%level%: %message% |
A Log::Abstraction format string. |
log_file |
empty (standard error) | Send diagnostics to this file instead. Leading directories are created. |
ssh_identity |
empty (ssh's default) | The default identity file for every SSH repo. |
ssh_known_hosts |
empty (ssh's default) | The default known-hosts file for every SSH repo. |
server_command |
filesync-server |
The program the client runs over ssh, unless the repo names another. |
Command output — sync summaries, plans, --json — is
written to standard output by the commands themselves. The logger carries
diagnostics on standard error, so a cron job can separate the two.
--verbose raises the level to debug and
--quiet lowers it to error for that run, overriding
the file.
Precedence
Lowest to highest:
- the built-in default;
- the
UNIVERSALsection; - the
App__FileSyncsection of the settings file orFILESYNC_SETTINGS; - the environment variables (universal ones first, class ones last);
--verboseor--quieton the command line, which describe this run only.
For a repo, a value recorded by filesync init —
--identity, --known-hosts,
--server-command — wins over the process setting, so one
machine can point at another identity without repeating the common settings.
port and host_key_checking exist per repo only:
there is no process-wide layer, and ssh's own default applies when the repo
leaves them out.
Where a value came from
filesync settings prints every effective value together with
the layer that supplied it, which is usually faster than reconstructing the
merge by hand:
$ filesync settings
settings file: /home/foo/.conf/app-filesync.json
log_level debug /home/foo/.conf/app-filesync.json [App__FileSync]
log_format %level%: %message% built-in default
log_file /home/foo/f.log App__FileSync__log_file
ssh_identity ~/.ssh/id_ed25519 built-in default
ssh_known_hosts built-in default
server_command /usr/local/bin/filesync-server /home/foo/.conf/app-filesync.json [App__FileSync]
The source is reported as default, file,
env, merged or repo in the JSON form.
A value that no modelled layer accounts for is reported as
merged rather than claimed as a default.
filesync settings --config FILE reads another settings file, and
--json returns the report as data.
Client configuration
The client keeps one JSON file listing its repos,
~/.filesync/config.json or the path in
FILESYNC_CONFIG. filesync init writes it atomically;
editing it by hand is fine, but keep the ids plain.
{
"version" : 1,
"client_id" : "laptop",
"ssh" : { "command" : "ssh", "extra_args" : [] },
"repos" : {
"documents" : {
"root" : "/home/foo/Documents",
"transport" : "ssh",
"server" : "foo@srv",
"role" : "client",
"identity" : "~/.ssh/filesync_ed25519",
"known_hosts" : "~/.ssh/filesync_known_hosts",
"server_command": "/home/foo/bin/filesync-server-home",
"snapshot_mode" : "hardlink"
}
}
}
| Key | Meaning |
|---|---|
client_id | This machine's id, the host name unless --id was given. It names this client's base, journal entries and conflict copies. |
repos.NAME.root | The local directory, which must contain the .filesync-root marker. |
repos.NAME.transport | ssh or local. |
repos.NAME.server | The ssh host, as host or user@host. |
repos.NAME.remote_repo | The repo name on the server, when it differs from this key. |
repos.NAME.role | client or replica; only a replica may take snapshots. |
repos.NAME.identity | ssh identity file for this repo. |
repos.NAME.known_hosts | ssh known-hosts file for this repo. |
repos.NAME.port | ssh port; repo only, default 22. |
repos.NAME.host_key_checking | yes or no; repo only, default yes. |
repos.NAME.server_command | The server program for this repo, such as the wrapper that adds --root. |
repos.NAME.snapshot_mode | hardlink or copy. |
repos.NAME.snapshot_keep | How many snapshots to keep; default 14. |
A configuration written by a newer release is read as-is: unknown keys are
kept and ignored, and there is no schema version check beyond
version. A missing file is an empty configuration rather than an
error.
Server repo policy
Each repo has a policy at
ROOT/.filesync/repos/REPO/config.json, created by
filesync-admin repo create and printed by repo show.
It holds the retention and deletion limits, the ignore list, and the admitted
clients.
{
"version" : 1,
"name" : "documents",
"created" : "2026-10-23 19:44:45 UTC",
"trash_days" : 30,
"max_deletes" : 200,
"max_delete_percent" : 10,
"conflicts" : "inline",
"preserve_mode" : true,
"allow_symlinks" : false,
"clients" : { "laptop" : { "role" : "client" } },
"ignore" : [ ".filesync-root", ".filesync-tmp-*",
".filesync-snapshots", "*.swp", "*~", ".#*",
"#*#", ".DS_Store", "._*", "Thumbs.db",
"desktop.ini", "*.crdownload", "*.part" ]
}
| Key | Default | Meaning |
|---|---|---|
trash_days | 30 | How long the server keeps deleted files. |
max_deletes | 200 | Most files one session may delete. |
max_delete_percent | 10 | Largest fraction of known files one session may delete. |
conflicts | inline | Keep the losing version beside the winner. |
preserve_mode | true | Carry permission bits between POSIX systems. |
allow_symlinks | false | Whether the tree may contain symlinks. |
clients | empty | Admitted client ids and their roles. An empty table admits every client. |
ignore | the list above | Patterns excluded on both sides. --ignore replaces the list; a trailing / matches at any depth, and a leading / anchors to the root. |
The reserved entries are not negotiable: the root marker, temporary files and snapshots must never enter a manifest, so they are excluded whatever the policy says.
Paths
| Path | Where | Holds |
|---|---|---|
~/.conf/app-filesync.json | client and server | Process settings, unless FILESYNC_SETTINGS names another file. |
~/.filesync/config.json | client | The repo list, unless FILESYNC_CONFIG names another file. |
~/.filesync/cache/REPO.json | client | The size-and-mtime cache and the last-run summary. |
~/.filesync/logs/REPO.jsonl | client | One JSON object per run attempt. |
~/.filesync/ | client | Also the per-repo lock and the local trash. FILESYNC_HOME moves the whole directory. |
ROOT/.filesync-root | client | The marker that proves the sync root is the registered tree and is mounted. |
ROOT/master/REPO/ | server | The master tree. |
ROOT/.filesync/repos/REPO/config.json | server | The repo policy and admitted clients. |
ROOT/.filesync/repos/REPO/ | server | The index, per-client bases, server trash and journal. |
ROOT/.filesync-snapshots/ | replica | Daily snapshots, one directory per date. |