vike-cli report
Ask a running vike-tradehub node for a live-journal tearsheet — read-only, and refused today because no node yet serves the capability.
report asks a running vike-tradehub node for a tearsheet over the live journal that node itself writes. It is read-only: the client always connects under the observe scope, and the call can neither place nor change anything. The journal itself never crosses the wire — the node renders the tearsheet and returns the answer as JSON.
It renders through the same vike_report::LiveTearsheet / crates/vike-report/src/tearsheet_cli.rs machinery report.rs's own doc names — pointed here at a live journal rather than a stored run, which is what puts the fills a running daemon is writing right now, on its own box, into the answer. It exists because that journal lives on the daemon's box — without this verb, getting a tearsheet over your own live trading meant opening an SSH session onto the production server.
Ruling 16 states the rule this verb closes a hole in: vike-cli <X> asks the backend to do X; vike-backend <X> does X here. Measuring the two command rosters against that rule found report served on the backend with no client half at all — report is the fix.
Every invocation refuses today
No vike-tradehub build advertises the tearsheet capability yet — the daemon-side renderer is a follow-up. So a report call that reaches a node always ends in a client-side capability refusal: nothing is sent to the node beyond the handshake, and stdout stays empty. This is deliberate — a capability advertised before its server-side renderer existed would turn a clean refusal into an opaque server error.
Usage
vike-cli report --node <host:port> [--seed CASH] [--periods-per-year N] [--json]vike-cli report --node prod2:9200 --seed 25000 --jsonThere is one form — no subcommands. --node is the only required flag; there is no default node to fall back to, the same shape trade status uses and for the same reason.
Flags
| flag | required | meaning |
|---|---|---|
--node HOST:PORT | yes | the node's observe address |
--seed CASH | no | the account's starting capital, which scales the return ratios; omitted means the node's own default |
--periods-per-year N | no | the Sharpe/Sortino/Calmar/CAGR annualization factor; omitted means the node's own default |
--json | no | the tearsheet JSON verbatim, unformatted, instead of pretty-printed |
-h, --help | no | print usage and exit |
A non-finite --seed or --periods-per-year is refused
Both flags reach the node as an optional number on the wire. serde_json writes a NaN or an infinite value as null, and the node would then silently apply its own default while you believed you had set one — so nan, inf, and -inf are refused by flag name before anything is sent, the same as a value that fails to parse at all.
Key resolution
The observe key resolves the same way every node key does: VIKE_TRADEHUB_OBSERVE_KEY in the process environment first, then <project>/settings/node.env — the same store the daemon itself reads. A control key cannot substitute here: the node verifies each scope against its own key, and report presents only the observe half. If no observe key resolves at all, the command exits before dialing the node and prints the keyring's own "no observe key" message instead.
Output
The node answers with the LiveTearsheet JSON document. --json prints that body verbatim; without the flag, the same document is pretty-printed. A body that fails to parse as JSON is reported as an error rather than echoed — a script reading stdout on a garbled body would otherwise see a success exit code.
The refusal, in full
A report call against a reachable node today prints three lines to stderr and exits 1 (stdout stays empty):
vike-cli report: this node does not advertise the "tearsheet" capability — Tearsheet refused client-side, nothing was sent
the node at prod2:9200 runs a vike-tradehub build with no server-side renderer for this verb. Until it has one, run the same renderer ON that box:
vike-backend report --journal <the node's journal directory> --seed 25000 --jsonThat third line is not a generic hint — it carries only the flags the failing invocation actually supplied (dropping --seed in translation would rescale every return ratio in the answer without saying so). The journal directory itself is never guessed; it is the node's own config.journal_dir or VIKE_JOURNAL_DIR, a fact this side of the wire cannot see, so the placeholder stays a placeholder.
If the observe key itself does not verify, the two lines differ and point at the credential instead of the verb:
vike-cli report: the node at prod2:9200 refused the observe handshake: auth denied: bad mac
the presented VIKE_TRADEHUB_OBSERVE_KEY does not match that node's — `vike-cli secrets path` names the store this side read it fromExit codes
| outcome | exit | retryable |
|---|---|---|
| node reachable, capability missing (today's outcome) | 1 | no — a permanent build fact |
| node reachable, observe key does not verify | 1 | no — fix the key, not the retry loop |
| node unreachable (refused, timed out, aborted) | 3 | yes |
A node that answered at all — even to refuse — exits on the permanent rung (1); only a socket that never got an answer exits on the retry rung (3). A wrapper that retried a permanent refusal would loop forever against a node that can never serve the call.
Related
- backend —
vike-backend reportis the renderer this verb's refusal points at today, run on the box holding the journal. - trade —
trade statusresolves its node key the same way and shares the same permanent-vs-retry exit rung rule. - secrets —
vike-cli secrets pathnames the store an observe-key mismatch was read from.