Configuration¶
lote reads three things. lote.toml says what to ship, ~/.ssh/config says where, and .lote/db.json remembers what happened. Everything else about a host is auto-discovered when you onboard it, so most setups never touch more than the [sync] table.
lote.toml¶
The repo-root lote.toml is essentially just the rsync scope. include is the allowlist of paths a compute node needs, and exclude skips heavy or regenerable patterns inside them.
[sync]
include = ["research", "toolbox", "pixi.toml", "chefe.toml"] # what to ship
exclude = [ # what to skip within them
"**/.venv",
"**/__pycache__",
"**/*.ckpt",
"**/wandb",
]
include paths are preserved with rsync -R, so the tree lands at the same place on the host. exclude patterns stack on top of your gitignore, which lote already honours, so you only list the extra heavy artifacts here. lote watch watches the same include set and re-syncs when any non-ignored file in it changes.
Targets and hints¶
Both are optional power-user overrides. By default targets come from ~/.ssh/config and every capability is probed, so you rarely set these.
targets = ["miyabi", "pegasus", "dgx-spark"] # restrict to these aliases
[hints.dgx-spark] # override a probed field
root = "/data/projects"
A targets list narrows lote to specific aliases instead of every host in your ssh config. A [hints.<alias>] table overrides a probed field for one host, its keys being the target's fields (root, kind, gpu_mem_mb, account, queue, and so on).
ssh targets¶
lote's targets are the concrete Host aliases in ~/.ssh/config. Pattern entries like Host * are ignored, leaving the real, connectable destinations.
Host dgx-spark
HostName 192.168.1.40
User pedro
Host miyabi
HostName miyabi.cc.example.ac.jp
User pedro
ProxyJump gateway
Host pegasus
HostName pegasus.example.ac.jp
User pedro
Because targets are ssh aliases, everything you already configure for ssh just works, including ProxyJump, identity files, and connection multiplexing. lote reuses one connection per command. There is no agent to install on the host and no control daemon to run, only ssh and, on each host, chefe so the executor can build and enter the env.
.lote/db.json¶
Run state lives in one TinyDB file at .lote/db.json. It holds three things, all written from your laptop.
| store | what it remembers |
|---|---|
| host facts | each onboarded host's probed scheduler, repo root, GPU, and account |
| run registry | every dispatch, with its handle, target, script, git sha, and --fetch path |
| command history | each lote invocation, timed, with its result |
lote ls reads the cached host facts without probing again. lote ps and lote pull read the run registry, so they work offline. lote history reads the command log, and a sibling .lote/lote.log keeps a rotated text trace. Set LOTE_NO_HISTORY=1 to skip recording. Onboarding writes a host's facts only after chefe install succeeds, so the registry only ever names machines that can actually run your jobs.