aura graph / render: expose rendering for a consumer's OWN graph (not just the built-in sample) #28
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Milestone fieldtest (Construction layer, docs/specs/fieldtest-milestone-construction-layer.md) headline friction:
aura graphrenders ONLY the built-in sample, and the render adapter lives in the aura-cli binary (crates/aura-cli/src/graph.rs) — it is not a public library API. So a downstream researcher who authors their own Blueprint can introspect it as data (the accessors work) but cannot RENDER it as an ASCII DAG without copying the CLI adapter.This is the milestone payoff only half-realized: "render the structure so any mis-wiring is visible before a run" is demonstrated on the engine sample, but a mis-wire lives in YOUR graph, not the sample. Same posture as
aura run(sample-bound), so it is consistent with the current CLI-demonstrator stage — but it is the natural next step.Direction (two coupled moves):
aura graphreach a consumer-authored graph (ties into the project-crate / cdylib loading of the World layer, C9/C17 — likely a later milestone).Subsumes the reachability of #26: the nested-composite clustered-render
unimplemented!is structurally unreachable from the public CLI TODAY (only the single-level sample renders), but becomes LIVE the moment the render is parameterizable. Sequence #26 to land with this.context: surfaced by the Construction-layer milestone fieldtest; no bug (sample render is correct + deterministic), friction = reach. Likely belongs to the next (consumer-project / World) milestone.
Re-scope — partially delivered since filing. Two of the three moves are done:
model_to_json(&Composite)is now public (aura-engine/src/lib.rs) andrender_html(&Composite)is parameterized on any composite (aura-cli/src/render.rs). The data + render path is no longer hardcoded to the built-in sample.What remains open is the reach, not the data path:
render_htmlstill lives in the aura-cli binary (no aura-cli lib target), so a consumer cannot call it on their own blueprint without copying the adapter.aura graphstill renders the built-in sample (main.rs); letting it reach a consumer-authored graph ties into project-crate / cdylib loading (C9/C17) and belongs to the later World/consumer-project milestone.The #26 nested-composite clustered-render path stays sequenced to land with move 1 — it goes live the moment the render is consumer-parameterizable.
Re-scope (recon 2026-06-18): two decoupled moves; defer both to the World / consumer-project milestone; drop the #26 coupling.
A code recon confirms the current state and corrects two stale premises in the body.
Data path — done (as the 2026-06-14 comment noted).
model_to_json(&Composite)is public (aura-engine/src/graph_model.rs:257, re-exported atlib.rs:59) andrender_html(&Composite)is parameterized on anyComposite(aura-cli/src/render.rs:64). No model/serializer work remains.Move (1) — public render entry-point — small, but its payoff is latent. The sole blocker is packaging:
render.rslives in a binary-only crate (aura-cli/Cargo.tomlhas only[[bin]], no[lib], nosrc/lib.rs), sorender_html— thoughpub— is unreachable by a downstream crate. The surface that would move is self-contained: onepub fn+ four private consts + threeinclude_str!'d JS assets (paths are crate-relative, soassets/moves with the code); the body is unchanged and the only call site ismain.rs:885.Recommended home: a dedicated render crate (
aura-viz), not a thin[lib]on aura-cli. Substance (not effort): #28 wants a reusable surface; the natural consumer edge isconsumer-project -> aura-viz -> aura-engine. A thin lib on aura-cli would force a consumer to import the CLI host crate (run/sweep/mc/walkforward machinery, arg-parsing, the sample builders) just to render — conflating host-binary with reusable library. A dedicated crate keeps render engine-only-dependent and asset-self-contained; C16 stays satisfied (the viz assets never touch aura-engine).Why defer move (1) rather than do it now: its entire value is reuse by a consumer project, and no consumer projects exist yet — recon found zero cdylib /
Aura.toml/ project-loader machinery anywhere in the repo. Today the only consumer is an in-repoexamples/fixture. Two substantive reasons to land it with the World / consumer-project milestone:render_htmlis one facet of that. Extracting a structure-onlyaura-viznow risks drawing the wrong crate boundary if the playground later wants structure + streams + traces in one viewer.aura new/ cdylib / deploy land after the World layer + experiment-API hardening), not the active orchestration-families milestone.Cost of waiting is ~zero: the sample renders, and an own graph is viewable ad hoc today via an example that emits
model_to_jsonand swaps it into the rendered viewer page.Move (2) —
aura graph <consumer-graph>— blocked on unbuilt infra. No cdylib / project-crate /Aura.tomlloading exists (only doc-comment prose).Compositeis not serde and there is nomodel_from_json, so the CLI cannot reconstruct a consumerCompositefrom a file — it needs a liveComposite, i.e. actual project-crate / cdylib loading (libloading +Aura.toml+ a Composite-export convention). This is the World / C9 / C17 seam — a later milestone, as the body already flags.#26 coupling — drop it. The
unimplemented!("nested-composite cluster rendering")this issue says to sequence with move (1) no longer exists: it lived incrates/aura-cli/src/graph.rs, retired with ascii-dag in cycle 0026 (commit66dff88). #26 is closed; nested composites render recursively in the JS viewer (graph-viewer.js) and are depth-2 guarded (viewer_nested_depth.rs). The only possible residue is a separate, unverified item from #26's body —SourceSpeccarries noname, so two F64 root sources render indistinguishably — which is not part of #28.Stale spec note (not a code gap):
docs/specs/fieldtest-milestone-construction-layer.mdstill describes ASCII-DAG output and anaura graph --compiledflag; both were retired in cycle 0026. Doc cleanup, handled separately.Net: both moves park in the World / consumer-project milestone — move (1) is a small
aura-vizextraction that lands first (unblocks a consumer rendering its own graph), move (2) depends on the cdylib loader. Nothing scheduled now.cycle-0088 fieldtest triage — detailed finding follows in a moment.
Reconfirmed from the op-script side — cycle-0088 fieldtest
The construction op-script service (#157) makes this gap concrete from the authoring direction.
aura graph buildemits aformat_version:1#155 blueprint to stdout, but no CLI subcommand consumes one back:aura graphignores stdin and renders the hard-wired sample (verified byte-identical with and without a piped blueprint), and there is noaura graph render <bp>/aura run <bp>. A pure-CLI consumer can now author topology as data and build it, but cannot render, run, or reload-validate the result through the CLI — the round-trip dead-ends at theblueprint_from_jsonlibrary boundary (#155).The missing edge this issue names (render a consumer's OWN graph) is now the same edge the op-script flow needs: a CLI path that takes either an op-list or an emitted #155 blueprint and renders/runs it. It is also why the acyclicity bug #161 is invisible to a CLI consumer — there is no compile/run path to surface a non-DAG.
Evidence:
fieldtests/cycle-0088-construction-op-script/FINDINGS.md(spec_gap "No CLI consumer for the emitted blueprint"). The render adapter being binary-private (noted in this issue's body,crates/aura-cli/src/render.rs) still holds —render_html(&Composite)is reachable only inside the binary.Triage 2026-07-09 (tree at
68317ec) — the 2026-06-18 deferral is fully unblocked; re-scoped to the CLI move:aura graphis now the ONE verb still sample-bound: the no-subcommand arm renders only the embedded examples/r_sma_open.json (crates/aura-cli/src/main.rs:2645-2654), while run/sweep/mc/walkforward/generalize all consume consumer blueprint files via is_blueprint_file (:2267).aura graph <blueprint.json>is: read file + blueprint_from_json(env.resolve) + render_html — the same pattern as dispatch_run.Design decision: CLI move only, drop the library-packaging half (/boss)
The 2026-07-09 triage flagged the library-packaging half — a dedicated,
downstream-linkable render crate (issue-body move #1) — for an explicit
re-decision rather than silent inheritance.
Decision: drop the library-packaging half; #28 is the CLI move only. Basis:
derived — the ratified consumer surface is CLI-over-blueprint-data (the
verb-dissolution milestone: a downstream researcher authors topology as data and
drives it through the
auraCLI, not by linking a Rust render library). Adedicated downstream-linkable render crate serves a consumer shape the project no
longer targets, and the CLI move fully realizes the milestone payoff — "render
YOUR graph to see mis-wiring before a run" — for the actual consumer surface.
Scope:
aura graph <blueprint.json>gains a first-positional blueprint andrenders it via
render_html, mirroringdispatch_run'sis_blueprint_filebranch (read file →
blueprint_from_json(env.resolve)→render_html); theno-argument form keeps rendering the embedded sample; the
build/introspect/registersubcommands are unaffected.The nested-composite concern (#26 — the old
graph.rsunimplemented!on acomposite-within-a-composite) is moot: that ASCII render was retired, the current
render.rs::render_htmlserializes viamodel_to_jsonwith no panic, and #26 isalready closed. No guard needed.