From 862882bc04ba5fc3b9f176911430c10045cbb827 Mon Sep 17 00:00:00 2001 From: Brummel Date: Tue, 9 Jun 2026 00:15:50 +0200 Subject: [PATCH] =?UTF-8?q?audit:=20cycle=200023=20(#48)=20=E2=80=94=20dri?= =?UTF-8?q?ft=20reconciled;=20render=20paths=20unified?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Architect drift review (bb90c42..481172a): no contract drift. C9 (render reads structure + label()/params()/output() only, never eval), C8 (sink = zero-output leaf, no special case), C12 (blueprint = root composite is render-structural only; types stay distinct), C23 (consumer-prefix mirrors the := binding), #38 (composites stay opaque) — all hold. Three fidelity items, resolved: - [high, fixed] spec acceptance over-claimed: the SimBroker slot-stub box read as in-scope though the work is deferred. Spec amended — the stub acceptance is annotated against #49, the met boxes checked. - [medium, recorded] no docs/plans/0023: this cycle ran spike→refactor under user steering instead of planner→implement, because the edge-label-vs- consumer-side fork needed an empirical probe (ascii-dag silently drops edge labels on collision) before a placeholder-free plan was possible. A plan RECORD (not a task plan) now holds the 0023 slot so the counter pairing stays intact and the next cycle takes 0024. - [low, carry-on] multi_output_field_name's leaf-producer fallback is latent and untested (no multi-output leaf in the corpus). Carried as debt. Regression scripts: none configured (no-op). Build/test/clippy green. Deferred stub work is tracked in #49 (user-signed). closes #48 --- docs/plans/0023-unify-blueprint-render.md | 51 +++++++++++++++++++++++ docs/specs/0023-unify-blueprint-render.md | 33 +++++++++------ 2 files changed, 71 insertions(+), 13 deletions(-) create mode 100644 docs/plans/0023-unify-blueprint-render.md diff --git a/docs/plans/0023-unify-blueprint-render.md b/docs/plans/0023-unify-blueprint-render.md new file mode 100644 index 0000000..de52b69 --- /dev/null +++ b/docs/plans/0023-unify-blueprint-render.md @@ -0,0 +1,51 @@ +# Unify the Blueprint Main-Graph Render — Implementation Record + +> **Parent spec:** `docs/specs/0023-unify-blueprint-render.md` +> +> **This is NOT a task-by-task plan.** Cycle 0023 was implemented through an +> exploratory spike→refactor path under direct user steering, not the standard +> `planner → implement` decomposition. This file exists to keep the +> spec/plan counter pairing intact (`naming.counter_dirs: [docs/specs, docs/plans]`) +> and to record *why* the standard plan artefact is absent, so the next cycle +> takes slot 0024 and a future reader does not mistake the gap for a lost file. + +**Goal:** one shared render path for the blueprint main graph and the composite +`where:` interior — the blueprint is the root composite. + +## Why no task-by-task plan + +The spec named the direction but left one detail to "the planner/implementer call +against ascii-dag's actual capability": *where* a multi-output producer's selected +field surfaces. Resolving it needed an **empirical** answer, not a paper decision: + +1. The obvious default (an ascii-dag per-edge label) turned out to be unreliable — + ascii-dag 0.9.1's `can_place_label` silently drops a label it cannot place + without collision (verified by throwaway probe against the real macd topology). + The Plain path drops it with no legend; the colored path shifts it to a legend. +2. So the field had to move to the **consumer node label** + (`[histogram → Exposure(scale)]`), which also removed the `render_flat` + signature change entirely (no edge-label slot). + +A placeholder-free plan could not be written before that probe, so the work ran as +a spike (validate the notation visually with the user) → refactor (collapse the +duplication into one shared `render_graph` over borrowed slices — `LeafFactory` +is not `Clone`, so an owned root-composite adapter is impossible). + +## What shipped (commits) + +- `5dd9503` — spec: 0023 unify blueprint main-graph render +- `481172a` — feat(aura-cli): unify blueprint main-graph render through one + shared core (`render_graph`; `ParamNames` {Aliases, Factory}; `Entry` unifying + `Role`/`SourceSpec`; deleted the duplicated `blueprint_leaf_label`) + +Production change confined to `crates/aura-cli/src/graph.rs`; goldens re-captured +in `crates/aura-cli/src/main.rs`. No engine change. Build/test/clippy green. + +## Deferred / debt (filed, not lost) + +- **Issue #49** — top-level blueprint multi-input leaves render without `#`-slot + stubs (`stub_ctx: None`); `fan_in_identifiers`/`signature_of` stays + composite-coupled. User-signed deferral. +- **Latent, untested** — `multi_output_field_name`'s leaf-producer fallback + (`from_field > 0` → index string) is unexercised (no multi-output leaf in the + current corpus); carried as latent code, no anchoring test this cycle. diff --git a/docs/specs/0023-unify-blueprint-render.md b/docs/specs/0023-unify-blueprint-render.md index 63e3f38..cef68e4 100644 --- a/docs/specs/0023-unify-blueprint-render.md +++ b/docs/specs/0023-unify-blueprint-render.md @@ -165,9 +165,12 @@ spec-owned): [Exposure(scale)] ← factory-declared param name, value-empty ``` -`SimBroker`, with two wired input slots (exposure, price), gains slot stubs the -same way the composite interior already shows them (e.g. `[SimBroker(#…,#…)]`); -`Recorder` (no params, one input, a sink) is unchanged — a bare terminal leaf. +`SimBroker`, with two wired input slots (exposure, price), would gain slot stubs +the same way the composite interior already shows them (e.g. `[SimBroker(#…,#…)]`) +— **deferred to issue #49**: as shipped, `SimBroker` renders bare, because +`fan_in_identifiers`/`signature_of` is still composite-coupled and threading the +blueprint case through it was carved out (user-signed). `Recorder` (no params, +one input, a sink) is unchanged — a bare terminal leaf. The headline is legibility: the histogram selection and `Exposure`'s parameterisation are now on the page. @@ -285,8 +288,8 @@ render has (the golden tests are byte-exact, layout is RNG-free). - **Golden re-capture, value-asserted (not just re-blessed).** `blueprint_view_golden` (`crates/aura-cli/src/main.rs:494`) is re-captured; the diff must show the new - information (a param name on `[Exposure …]`, slot stubs on `[SimBroker …]`), - proving enrichment rather than a blind re-bless. + information (a param name on `[Exposure …]`; the `[SimBroker …]` stubs are + deferred to #49), proving enrichment rather than a blind re-bless. - **The headline assertion (macd):** a test on `render_blueprint(&macd_blueprint())` asserts the macd→Exposure edge surfaces `histogram` and that `[Exposure(scale)]` shows its param — the legibility property the cycle exists to buy. Extends the @@ -324,13 +327,17 @@ Against aura's feature-acceptance criterion (CLAUDE.md): Concretely, the cycle is done when: -- [ ] `aura graph --macd`'s main graph shows the `histogram` field on the - macd→Exposure connection and `scale` on the `Exposure` leaf. -- [ ] `SimBroker`'s two input slots render as stubs in the main graph (the same - enrichment the composite interior already shows). -- [ ] Single-output producers carry no field label; the sma_cross sample golden +- [x] `aura graph --macd`'s main graph shows the `histogram` field on the + macd→Exposure connection and `scale` on the `Exposure` leaf. (Shipped as a + consumer-side prefix `[histogram → Exposure(scale)]`, not an edge label — + ascii-dag drops edge labels on collision; see Architecture.) +- [ ] **Deferred to #49.** `SimBroker`'s two input slots render as stubs in the + main graph (the same enrichment the composite interior already shows). As + shipped, `SimBroker` renders bare — the stub machinery stays + composite-coupled this cycle. +- [x] Single-output producers carry no field label; the sma_cross sample golden shows no spurious labels. -- [ ] The `where:` section's existing assertions still pass (unchanged in spirit). -- [ ] Composites remain opaque in the main graph (#38 retained). -- [ ] `cargo test --workspace` and clippy are green; goldens re-captured with +- [x] The `where:` section's existing assertions still pass (unchanged in spirit). +- [x] Composites remain opaque in the main graph (#38 retained). +- [x] `cargo test --workspace` and clippy are green; goldens re-captured with visible new information.