diff --git a/README.md b/README.md index 0ce9615..2bca8e9 100644 --- a/README.md +++ b/README.md @@ -43,8 +43,9 @@ Invoke it as `aura …` (examples below use the plain name). ## Running & orchestrating a loaded blueprint -These verbs all take the **blueprint file as their first positional argument** -and drive a family of runs over it. `walkforward`, `mc`, and `generalize` share +These verbs all take the **blueprint file as their first positional argument**. +Most drive a family of runs over it; `graph` renders its structure so a mis-wire +is visible before a run. `walkforward`, `mc`, and `generalize` share `sweep`'s generic grammar — the blueprint positional plus `--real` and a repeatable `--axis =` (`generalize` takes `--real `, at least two instruments, with a single value per axis) — see `--help`. @@ -52,6 +53,7 @@ least two instruments, with a single value per axis) — see `--help`. | Command | Purpose | |---|---| | `aura run ` | Run one backtest of a **closed** blueprint and print its report. An open (free-knob) blueprint is refused with a clean error — bind it, or use `sweep`. | +| `aura graph ` | **Render** the blueprint's structure as an interactive HTML DAG so a mis-wire is visible before a run. Omit the file to render the built-in sample; a named-but-unreadable file is a usage error. | | `aura sweep --list-axes` | **Discover** the blueprint's open, sweepable knobs. Prints each as `:`. Run this first to learn the axis names. | | `aura sweep --axis = [--axis …]` | Run a **grid family** over the named axes and persist it. | | `aura mc --seeds ` | Run a **synthetic Monte-Carlo family** of `n` seeded realizations. Wants a **closed** blueprint (the inverse of sweep). | diff --git a/crates/aura-cli/src/main.rs b/crates/aura-cli/src/main.rs index 42ce15e..0a205e6 100644 --- a/crates/aura-cli/src/main.rs +++ b/crates/aura-cli/src/main.rs @@ -2685,7 +2685,7 @@ fn dispatch_graph(a: GraphCmd, env: &project::Env) { }); print!("{}", render::render_html(&bp)); } - None => { + None if a.blueprint.is_none() => { let bp = blueprint_from_json( include_str!("../examples/r_sma_open.json"), &|t| env.resolve(t), @@ -2693,6 +2693,14 @@ fn dispatch_graph(a: GraphCmd, env: &project::Env) { .expect("the shipped r-sma example reloads into a renderable blueprint"); print!("{}", render::render_html(&bp)); } + None => { + eprintln!( + "aura: Usage: aura graph [] [build|introspect|register]; \ + {} is not a readable .json blueprint", + a.blueprint.as_deref().unwrap_or_default() + ); + std::process::exit(2); + } }, Some(GraphSub::Build) => graph_construct::build_cmd(env), Some(GraphSub::Introspect(i)) => graph_construct::introspect_cmd(i, env), diff --git a/docs/authoring-guide.md b/docs/authoring-guide.md index dda5834..9c2605c 100644 --- a/docs/authoring-guide.md +++ b/docs/authoring-guide.md @@ -86,7 +86,10 @@ $ aura graph build < smacross.json "input_roles":[{"name":"price",...,"source":"F64"}],"output":[...]}} ``` -Introspection is build-free wherever possible: +The built blueprint renders visually, too: `aura graph blueprint.json` emits an +interactive HTML DAG so a mis-wire is visible before any run (`aura graph` with +no file renders the built-in sample; a named-but-unreadable file is a usage +error). Introspection is build-free wherever possible: ``` $ aura graph introspect --vocabulary # one node type per line