vike
Trade

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 --json

There 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

flagrequiredmeaning
--node HOST:PORTyesthe node's observe address
--seed CASHnothe account's starting capital, which scales the return ratios; omitted means the node's own default
--periods-per-year Nnothe Sharpe/Sortino/Calmar/CAGR annualization factor; omitted means the node's own default
--jsonnothe tearsheet JSON verbatim, unformatted, instead of pretty-printed
-h, --helpnoprint 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 --json

That 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 from

Exit codes

outcomeexitretryable
node reachable, capability missing (today's outcome)1no — a permanent build fact
node reachable, observe key does not verify1no — fix the key, not the retry loop
node unreachable (refused, timed out, aborted)3yes

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.

  • backend — vike-backend report is the renderer this verb's refusal points at today, run on the box holding the journal.
  • trade — trade status resolves its node key the same way and shares the same permanent-vs-retry exit rung rule.
  • secrets — vike-cli secrets path names the store an observe-key mismatch was read from.

On this page