-
Notifications
You must be signed in to change notification settings - Fork 1
Running S9TerpSync
This page is for the operator doing a manual run. It covers the three run commands — run, run resume, and run recover-lock — and, most importantly, how --dry-run and --live differ across all three of them. It doesn't cover scheduled or service-supervised runs (that's Service & Systemd Operation), and it doesn't cover cleaning up after a partially-failed run beyond run resume itself (that's Retention, Replay & Recovery).
Every command on this page takes exactly one of --dry-run or --live — never both, never neither. Passing both, or passing neither, fails before anything runs, with a message to the effect of "specify exactly one of --dry-run or --live" and exit code 1.
-
DRY_RUNwalks the same logic as a live run — reading the source, matching records, planning what would change — but never writes to Ethos/Banner. Forrunandrun resume, that's the only difference from--live: both modes acquire the sharedrunlock before doing anything else, so aDRY_RUNstill contends with any other in-progressrun,run resume, orretention run, and can fail withrun lock already held, exit3, just like--livewould (see Diagnostics & Troubleshooting).run recover-lockis the one exception on this page — both of its modes go through a separate recovery mechanism and never acquire the sharedrunlock at all; itsDRY_RUNreports which locks are eligible for recovery without recovering them. Aside from that exception, dry-run is safe to run repeatedly and is the right default for validating a configuration or investigating a stuck run before committing to anything irreversible. -
LIVEperforms the real mutation:runandrun resumewrite to Ethos (which Banner then reflects);run recover-lockactually clears a stale run lock so a new run can start.
flowchart TB
trigger["Operator runs a command<br/>run · run resume · run recover-lock"]
mode{"--dry-run or --live?<br/>exactly one is required"}
dryPath["DRY_RUN<br/>plan/report only, no writes<br/>(run/run resume still take the run lock)"]
dryOutcome["Outcome reported<br/>nothing in Ethos or Banner changed"]
livePath["LIVE<br/>the real mutation runs"]
liveOutcome["Outcome reported<br/>Ethos/Banner updated, or the stale lock recovered"]
trigger --> mode
mode -->|--dry-run| dryPath
mode -->|--live| livePath
dryPath --> dryOutcome
livePath --> liveOutcome
classDef pipeline fill:#EEEDFE,stroke:#534AB7,color:#26215C
classDef mutation fill:#FAECE7,stroke:#993C1D,color:#4A1B0C
classDef failure fill:#FAEEDA,stroke:#854F0B,color:#412402
classDef readonly fill:#E1F5EE,stroke:#0F6E56,color:#04342C
classDef neutral fill:#F1EFE8,stroke:#5F5E5A,color:#2C2C2A
class trigger,mode neutral
class dryPath,dryOutcome readonly
class livePath,liveOutcome mutation
s9terpsync run --file <path> [--source <source>] (--dry-run | --live)
The manual intake run: reads the configured source once, matches and plans changes, and (in --live mode) writes them to Ethos.
-
--file— path tos9terpsync.yaml. Not enforced as a CLI-required option, but the command fails immediately (run failed, exit1) if it's omitted — treat it as required. -
--source(optional) — which configured source to read from:sftporslate-api. Any other value fails withrun source: specify sftp or slate-api. If omitted, the source is auto-detected from the config: if exactly one ofsources.sftp.enabled/sources.slateApi.enabledistrue, that one is used automatically; if the config has more than one source enabled, you must pass--sourceexplicitly, or the command fails withrun source: specify --source when multiple sources are enabled. -
--dry-run/--live— exactly one is required (see Dry-run vs. live above).
On success it prints two lines:
run completed <runId> <status> files=<n> records=<n> succeeded=<n> failed=<n>
report path=<relativePath> checksum=<checksum> sizeBytes=<n>
<status> is one of NO_DATA (nothing new to process), COMPLETED (everything succeeded), or COMPLETED_WITH_ERRORS (some records failed). A COMPLETED_WITH_ERRORS status also makes the command exit 2 — see Diagnostics & Troubleshooting for what each exit code means across the CLI.
Example:
s9terpsync run --file ./s9terpsync.yaml --source sftp --dry-runs9terpsync run resume <run-id> --file <path> (--dry-run | --live) [--retry-token <token>]... [--retry-manifest <id>] [--retry-all]
Resumes a prior Slate API run — typically one left incomplete after a failure — instead of starting a fresh one. <run-id> (positional) is the run to resume.
-
--file(required) — path tos9terpsync.yaml. -
--dry-run/--live— exactly one is required, same rule asrunabove. -
--retry-token <token>— an opaque selected-record retry token, identifying one specific record to retry. Repeat the flag to retry several records (--retry-token abc --retry-token def); duplicate tokens are rejected. -
--retry-manifest <manifest-id>— an opaque retry manifest ID (created withreplay retry-manifests create; see Retention, Replay & Recovery) selecting the set of records it lists. -
--retry-all— retry every currently eligible record from the original run, with no explicit selection needed.
--retry-token, --retry-manifest, and --retry-all are mutually exclusive — combining any two of them (for example --retry-all with a --retry-token, or --retry-manifest with either of the others) fails with run resume failed, exit 1. Passing none of the three is allowed — it resumes the run without selecting specific records to retry.
On success it prints:
run resume sourceRunId="<run-id>" resumedRunId="<new-run-id>" status="<status>" files=<n> records=<n> succeeded=<n> failed=<n>
report path=<relativePath> checksum=<checksum> sizeBytes=<n>
As with run, a COMPLETED_WITH_ERRORS status makes the command exit 2.
Example:
s9terpsync run resume 2026-08-01T02-00-00Z --file ./s9terpsync.yaml --retry-all --lives9terpsync run recover-lock --file <path> --older-than-minutes <minutes> (--dry-run | --live)
Recovers a run lock that's been held longer than expected — for example, after a process crashed mid-run without releasing it — so a new run can start. This is the manual, CLI-driven counterpart to service recover-lock (covered on Service & Systemd Operation); this one targets the CLI's own run lock, not the service's.
-
--file(required) — path tos9terpsync.yaml. -
--older-than-minutes(required) — a positive integer. Only locks held longer than this many minutes are eligible for recovery; anything else (zero, negative, non-numeric) fails validation. -
--dry-run/--live— exactly one is required, same rule as above.DRY_RUNreports which locks are eligible without touching them;LIVEactually recovers them.
On success it prints:
run lock recovery <mode> status=<status> scanned=<n> eligible=<n> recovered=<n> skipped=<n> failed=<n>
In LIVE mode, if any recovery attempt failed, the command exits 2.
Example:
s9terpsync run recover-lock --file ./s9terpsync.yaml --older-than-minutes 60 --dry-run-
Retention, Replay & Recovery — inspecting an incomplete run's records, creating the retry manifests
run resume --retry-manifestconsumes, and the separateretentioncommands. - Service & Systemd Operation — running S9TerpSync unattended on a schedule instead of by hand, and the service's own lock recovery.
- Diagnostics & Troubleshooting — what each exit code means, and how to check a config against your live environment before you run it for real.