Skip to content

Latest commit

 

History

History
469 lines (362 loc) · 32.9 KB

cli.md

File metadata and controls

469 lines (362 loc) · 32.9 KB

CLI reference

Nine public commands, and vigil --help names every one of them:

Command What it does
vigil run Starts the camera runtime, the local store, the health and review servers, and the owner channel every command below is answered on
vigil events Lists this deployment's recent landed detection events, newest first
vigil why Walks one detection back through its camera, site, detector Decision, baseline Intention and evidence
vigil stats Prints this deployment's own persisted snapshot of pipeline counters and health
vigil settings Reads and changes what this deployment is configured to run at, and reports what it is running at now
vigil enroll Names the subject in a detection, so later sightings match that name
vigil forget Removes this site's recognition references for a named subject
vigil doctor acceleration Reports the decode and detection acceleration this host actually offers
vigil fabric ticket Prints this node's fabric enrollment ticket, on explicit invocation only

A tenth command is dispatched and deliberately kept off that list: vigil detector-probe belongs to the detection-probe machinery rather than to an operator, and is described under Detector probe. This page documents each public command and the answers it gives.

Run

vigil run [OPTIONS]

Starts the camera runtime, local store, health server, review server, the owner channel the CLI reaches this process on, and configured Home Assistant and recognition tasks.

If another process is reading this deployment's store when the runtime starts, the runtime waits for it rather than failing. It says on its startup output that it is waiting and what it is waiting for, and it starts normally the moment the reader finishes. There is no timeout on that wait and no setting that shortens it: a reader that is genuinely working is not a fault, and a runtime that gave up on one would leave a healthy node down for a condition that was about to clear.

Common options:

Option Meaning Default
--config PATH Read a TOML configuration file none
--data-dir PATH Runtime data root ./vigil-data
--store-path PATH Context Graph store <data-dir>/store.contextgraph
--health-port PORT Health HTTP port 8099
--review-port PORT Review HTTP port 8098
--site-name NAME Site/context name site-1
--camera-name NAME Single-camera name camera-1
--rtsp-url URL Detection stream none
--live-rtsp-url URL Separate Home Assistant live stream detection URL
--usb-device IDENTITY Legacy single-camera USB source none
--csi-module IDENTITY Legacy single-camera CSI source none
--mjpeg-url URL Legacy single-camera MJPEG source none
--rtsp-username USER RTSP username outside the URL none
--rtsp-password PASSWORD RTSP password outside the URL none
--detector-model-id ID Model identity written to provenance yolox-tiny-burn-cpu
--detector-model-path PATH Detector weights path artifact/config dependent
--detector-confidence-threshold FLOAT Keep detections at or above this value 0.5
--detector-sample-frames N Frames sampled per segment 5
--detector-stationary-interval-secs N Sampling interval for stationary scenes 30
--recognition-weights-dir PATH Enable recognition with local weights disabled
--hardware-decoding BOOL Request hardware-decode probing true
--accelerated-detection BOOL Request accelerated-detector probing true
--fabric-ticket TICKET Join an existing configured fabric none
--fabric-hub BOOL Start the node as a fabric join point false
--fabric-allow-frame-offload BOOL Permit this node's detector work to move true
--fabric-worker-lease-ms MS Fabric worker lease setting 300000
--fabric-fallback-horizon-ms MS Remote-result wait setting 5000

Developer-preview fabric warning: default builds omit fabric entirely. In a fabric-enabled build, remote or rescued detector jobs can currently return empty detection content, and the two tuning fields are not both production-wired. Do not treat these flags as an operational distributed-compute surface.

The confidence threshold must be between 0.0 and 1.0; sampled frames must be between 1 and 64; booleans accept true or false. Multi-camera lists and MQTT are configured through TOML or add-on options rather than repeated CLI flags. Recognition class coverage (recognition_covered_classes) is configured through TOML or add-on options; it is not an environment variable. Service identity is not a TOML or add-on field at all — an ordinary vigil settings set service_identity is refused, and moving it is its own deliberate operation, vigil settings identity change <identifier> --confirm (see Configuration).

Events

VIGIL_DATA_DIR=/var/lib/vigil vigil events

Lists up to 100 recent landed detection events, newest first. It does not list motion-only segments or correction observations.

/var/lib/vigil must match the running daemon's data_dir. Review commands do not read its --config TOML; without VIGIL_DATA_DIR or an exact VIGIL_STORE_PATH, they use ./vigil-data and can silently read a different store.

With its local store selected explicitly, vigil events reads landed events and orders them newest observed first.

An empty result is an empty answer, not a refusal and not a manufactured row. On a deployment nothing has run in, vigil events prints nothing at all and exits 0 — there are no events, and that is what was asked. vigil why --latest is the opposite case on the same deployment: it could not serve the request, because there is no event to walk, so it refuses on standard error with exit status 2.

Where a running owner serves that empty answer instead, the whole of it is the served-by=af_unix line with nothing beneath it.

Why

VIGIL_DATA_DIR=/var/lib/vigil vigil why <detection-id>
VIGIL_DATA_DIR=/var/lib/vigil vigil why --latest

vigil why --latest selects the newest observed detection and walks its camera, site, detector Decision, baseline Intention, and evidence. An unknown UUID returns a clean not-found error.

A malformed detection ID is refused as a malformed ID and never reported as a missing event: the answer names what was typed and the form a detection ID takes, so an operator who mistyped one is not sent looking for a recording nobody ever named.

Omitting the why argument currently behaves as --latest. The mapped tests do not exercise that CLI form directly.

Stats

VIGIL_DATA_DIR=/var/lib/vigil vigil stats

vigil stats prints the runtime's local persisted snapshot of pipeline counters and health.

Those figures come from this deployment's own snapshot file, <data-dir>/runtime-stats.json, and vigil stats opens no store to read them. The answer opens with a stats-provenance= line whenever the figures are not a reading of a running node. stats-provenance=not-started says nothing has run in this data directory yet and names the directory it looked in, so an all-zeros answer from a mistyped VIGIL_DATA_DIR is not read as a quiet node; stats-provenance=stopped-run says these are the last figures this deployment's own run wrote before it ended, carried under a line saying they are a record and not a reading. A live run's figures carry no such line, and that absence is what says they are current. A snapshot whose writer cannot be established at all — truncated, unreadable, or carrying no ownership stamp — is refused rather than served as either.

If a fabric is configured, shared fabric status and join instructions are intended to appear on this surface as well; the local-counter witness does not exercise a fabric-configured CLI invocation.

Settings

VIGIL_DATA_DIR=/var/lib/vigil vigil settings
VIGIL_DATA_DIR=/var/lib/vigil vigil settings list
VIGIL_DATA_DIR=/var/lib/vigil vigil settings find <TEXT>
VIGIL_DATA_DIR=/var/lib/vigil vigil settings set <SETTING> <VALUE>
VIGIL_DATA_DIR=/var/lib/vigil vigil settings reset <SETTING>
VIGIL_DATA_DIR=/var/lib/vigil vigil settings identity
VIGIL_DATA_DIR=/var/lib/vigil vigil settings identity change <IDENTIFIER> --confirm

Every one of these asks the process that owns this deployment's store, through Context Graph's authenticated owner channel, and reads the store file directly only when no runtime is holding it. Both routes render the same report; an answer the running owner served opens with a served-by=af_unix line, and an answer read from an idle store file carries no such line. Neither route brings anything into existence: asking a deployment that has never started what it would run at leaves its data directory exactly as it was, with no store on disk afterwards.

vigil settings and vigil settings list are the same listing. It is six kinds of line — served-by, identity, setting, held, domain and secret — and every field each kind carries, with its value set, is in the settings listing's field glossary, beside the table that says which surface may author each field.

vigil settings find <TEXT> searches the same listing and answers with every line containing that text — setting lines, the domain switch= control lines and the explanations alike, because the search is over the whole rendered answer and that breadth is deliberate. A search that matches nothing succeeded and found nothing: the answer is empty and the exit status is 0. A search with no text names nothing to look for, so it is a usage error.

vigil settings set <SETTING> <VALUE> records the value at this deployment through the vigil-settings surface and then prints the listing back; a bare true or false is a switch, a bare number is a number, a comma-separated value is a list, and anything else is text. vigil settings reset <SETTING> withdraws this deployment's own record for that setting, states what the withdrawal leaves in force, and prints the listing beneath it. A change made against the running node takes effect on that node before the answer is rendered where the setting is one the process can take on live; where only a start brings it into force, the line says so with applies=next-restart.

vigil settings identity prints this node's service identifier and how it was arrived at, and it is read-only. The identifier is not an ordinary setting: vigil settings set service_identity is refused, naming the orphaned-history consequence, and so is a reset of it. Moving it is its own deliberate operation. vigil settings identity change <IDENTIFIER> without --confirm states the consequence and changes nothing, so the consequence is read before the identity moves; with --confirm the change is recorded and takes effect at the next start.

What each of these shapes answers when another process is reading the store, when nothing has ever run in this directory, when another runtime owns the store, and when the store cannot be read at all — and which stream and exit status each of those answers arrives on — is stated once, in When a read command cannot open the store.

Enroll

VIGIL_DATA_DIR=/var/lib/vigil vigil enroll <detection-id> <name>

The underlying enrollment operation creates a named site-local recognition reference from a detection and writes its linked correction. The detection must carry the stored recognition probe; when it does not, enrollment fails without a stranded correction row.

The vigil enroll command is dispatched to this operation, but the current deterministic witnesses invoke the operation directly rather than through the CLI.

Forget

VIGIL_DATA_DIR=/var/lib/vigil vigil forget <name>

The underlying forget operation removes site-local recognition references for the named subject; later sightings then stop matching that subject.

The vigil forget command is dispatched to this operation, but the current deterministic witness invokes the operation directly rather than through the CLI.

Doctor acceleration

vigil doctor acceleration [--service-user USER] [RUN_OPTIONS]

The acceleration report renders decode and detection receipts in a fixed order with configured, status, attempted-backend, active-backend, and failure-code fields. Without sudo, it reports the current process's usable software and CPU fallback state.

The command is intended to be read-only, include an operator action for each fallback, and use the same relevant probes as feature-enabled runtime startup. The current mapped tests call the report logic directly and do not bind all three CLI-level assertions.

Fabric ticket

vigil fabric ticket [--data-dir PATH]

Prints this node's fabric enrollment ticket to stdout, on explicit invocation only. The ticket is a credential, held to a two-tier contract. On every displayed or served surface — logs, vigil stats, vigil doctor, the /health HTTP body — it is deliberately absent, with exactly two sanctioned retrieval paths: vigil run's own startup log, which still prints it as a sanctioned operator-facing instruction, and this command, which falls back to the ticket the running node cached the last time it bound (since a live rebind opens the same on-disk fabric ledger the running node's own Database::open already holds, which fails fast with a typed writer-held refusal before this command ever reaches its own endpoint bind step). Separately, it is expected to sit in exactly two private, tight-permissioned (owner-read/write only) persisted stores: the fabric/own-ticket cache this command falls back to, and the fabric ledger (fabric/fabric-ledger.db), whose peer-directory table is the fleet's own coordination mechanism — reading either already requires filesystem access to this node's data directory.

Detector probe

vigil detector-probe is an internal subprocess command used by the detection-probe machinery. It is not an operator workflow and its wire arguments are intentionally omitted here.

When a read command cannot open the store

Four different things stop a read command opening this deployment's store, and they are four different answers because they send you to four different places. Every one of them is decided on the typed condition the layers below report, never on the wording of a message, and none of them writes to your store.

Somebody is reading it. Another process — a second command, or this node's own reader — holds the store while it hydrates. Nothing you only ASK notices: vigil settings, vigil settings list, vigil settings find <text>, vigil settings identity, vigil why and vigil events all read through a door that coexists with other readers, so they are served their ordinary answer and name nobody. vigil enroll and vigil forget are the two that wait, because they change what this node recognizes and that needs the store to itself. They say so on a busy line naming the store and how many readers hold it, followed by a reader line per reader carrying that reader's process id and process name, so you can go and look at the one that is in the way. The store is healthy, nothing needs repairing, and the condition clears on its own: run the same command again once they finish and it lands. It is not the unreadable answer — nothing tells you the store cannot be read, and nothing calls this node unmanaged.

Nothing has ever run here. There is no store because no runtime has started in this directory. Nothing is broken and nothing needs repairing, so no answer sends you to repair anything: vigil events answers with no events, vigil why refuses because there is no event to walk, vigil stats and the read-only settings shapes answer what this node would run at, and vigil enroll and vigil forget refuse because there is nothing here yet to correct. Whichever you ask, asking leaves the directory exactly as it was — no command in this family brings a deployment into existence, so a command pointed at the wrong path does not turn that path into a deployment.

Another runtime owns it. A writer holds the store, and it keeps holding it until that runtime lets go. That is one condition however it is reached: the same refusal whether the writer is this process or another one, spelled by type rather than by matching text.

It cannot be read at all. A corrupt file or an unreadable volume is a storage problem. Here the answer names the store and says this deployment's settings and this node's identity are not available through this command, and where they are. What it deliberately does not do is print a settings listing, a domain roster or an identity: this process never read your store, so every one of those would be a value it made up — the artifact's own defaults standing where your deployment's belong, with nothing on the line to say so.

vigil stats is the exception to all four conditions, because it never opens the store: its figures come from <data-dir>/runtime-stats.json, so it answers normally at exit 0 — under its own stats-provenance= line — however badly the store is faring. The condition it has of its own is a snapshot whose writer cannot be established, which it refuses.

How each answer is delivered does not change with which of the conditions produced it, for every condition a command actually meets. vigil why and vigil events could not serve your request, so they refuse: the answer is on standard error and the exit status is 2. The vigil settings, vigil settings list and vigil settings find <text> listings were served — the explanation is the answer — so they arrive on standard output. vigil settings identity is a failed request whichever way it fails: an operator asked this node what it is called and no answer exists to give them, so it leaves on standard error with exit status 2 rather than letting a script read a missing identity as a successful lookup. A settings change refuses too, on the same terms, because a change nothing recorded is not a change. The reader condition is the one no question ever meets: everything you only ask reads through a door that coexists with other readers, so a store somebody is reading answers with your settings, your node's identity and your review history exactly as an idle store does.

One refusal sits outside those four, because the store is not what is in the way. A running owner serves a bounded number of these requests at a time — four, on the shipped limits — and a request that arrives while that many are already in flight is refused rather than queued. The answer is the process holding the store at <path> is already serving as many requests as it admits, on standard error with exit status 2, and that holds for every command in the family: it is a live owner speaking for itself, so no command may go behind it and read the store instead. It is neither the busy answer nor the unreadable one — nothing needs repairing, and the same command answers normally once the requests in flight have landed — and it is the one condition under which a read-only settings shape does not deliver its answer on standard output.

Global options

Option Meaning
--version Print the Vigil package version
--help, -h Print the current built-in help

Unavailable commands

The current binary has no status, health, config check, config validate, correct, state-at, why-flagged, scan onvif, scan rtsp, or support-bundle command. Health is an HTTP endpoint, corrections use Home Assistant/MQTT or the review HTTP API, and configuration validation happens while vigil run loads its inputs. These names remain unavailable until implemented and tested.