# Fieldtest transcript — cycle #331 (blueprint name op) Source-blind consumer field test of the eleventh op-script op `{"op":"name","name":""}` — the composite render name that flows to store documents, `traces//`, and `use`-splice instance defaults, gated by a deterministic shape check at every authored intake. Binary: `target/release/aura`, built from HEAD `4ff85b9` via `cargo build --release -p aura-cli` (Finished in 5.48s — HEAD builds clean). Scratch project `aura new nm_lab` in `/tmp/ftwork/nm_lab`; real data from the built-in archive (US500). Public interface only (README, authoring-guide, glossary, design ledger C23/C24/C29, `aura … --help`) — no crate source read. --- ## Example 1 — authoring loop end to end (`c331_1_named_crossover.ops.json`) A named SMA-crossover with a `spread` tap, all knobs bound (closed → runnable). ``` $ aura graph build < c331_1_named_crossover.ops.json > c331_1_named_crossover.bp.json # exit 0 # blueprint.name == "ny_momentum", taps == [{"name":"spread",...}] $ aura graph register c331_1_named_crossover.bp.json registered blueprint 347a361997e8a65d4122b5ab50367031f78df24a1ff6ad14477ed2c04ec3b603 (…) # store doc runs/blueprints/347a…json -> name: ny_momentum $ aura run c331_1_named_crossover.bp.json --real US500 --tap spread=mean # exit 0 $ find runs/traces runs/traces/ny_momentum runs/traces/ny_momentum/index.json runs/traces/ny_momentum/spread.json ``` The authored name `ny_momentum` shows up in all three documented places — the blueprint bytes, the store document's `name`, and the run's trace directory `traces/ny_momentum/`. (Finding W1.) ### Default collision story (omitting the name) Two *different* unnamed crossovers (A: fast=3/slow=8, B: fast=5/slow=20), both build to `name: "graph"`, both `--tap spread=record` over US500: ``` $ aura run c331_1b_unnamed_A.bp.json --real US500 --tap spread=record # exit 0 sha256(runs/traces/graph/spread.json) = 5bb5dcfc… $ aura run c331_1c_unnamed_B.bp.json --real US500 --tap spread=record # exit 0 sha256(runs/traces/graph/spread.json) = 3be8025b… ← overwritten, silently $ ls runs/traces/ → graph ny_momentum ``` Both unnamed strategies share `traces/graph/`; B silently overwrote A's `spread.json` (differing sha). This is exactly the documented "later runs overwrite earlier ones" consequence — observable, no warning (as documented). (Finding W1.) --- ## Example 2 — refusal battery (`c331_2*`) ### Op route (op-indexed prose) ``` $ aura graph build < c331_2a_dup_name.ops.json # exit 1 aura: op 1 (name): a script names its blueprint at most once $ aura graph build < c331_2b_slash_name.ops.json # exit 1 aura: op 0 (name): blueprint name "traces/evil" is invalid: must not contain '/' or '\' (a single path segment) $ aura graph build < c331_2c_empty_name.ops.json # exit 1 aura: op 0 (name): blueprint name "" is invalid: must be non-empty (a single path segment) $ aura graph build < c331_2d_dotdot_name.ops.json # exit 1 aura: op 0 (name): blueprint name ".." is invalid: must not be "." or ".." (a single path segment) ``` Each refusal is op-indexed, quotes the offending name, and states the exact rule. Copy-paste fixable. (Finding W2.) ### Hand-edited envelope with a bad root name (`../escape`) `c331_2e_open_named.bp.json` (clean name `clean_name`, `fast.length` open), root `name` hand-edited to `../escape` → `c331_2e_badroot.bp.json`, fed to every file intake: ``` $ aura graph register c331_2e_badroot.bp.json # exit 1 GATED aura: blueprint name "../escape" is invalid: must not contain '/' or '\' (a single path segment) $ aura run c331_2e_badroot.bp.json --real US500 # exit 2 GATED aura: …/c331_2e_badroot.bp.json: blueprint name "../escape" is invalid: … $ aura sweep c331_2e_badroot.bp.json --axis fast.length=2,4 # exit 2 GATED aura: blueprint name "../escape" is invalid: … $ aura graph introspect --content-id c331_2e_badroot.bp.json # exit 1 GATED $ aura graph introspect --params c331_2e_badroot.bp.json # exit 1 GATED $ aura graph c331_2e_badroot.bp.json # exit 2 GATED aura: …/c331_2e_badroot.bp.json: blueprint name "../escape" is invalid: … $ aura sweep c331_2e_badroot.bp.json --list-axes # exit 0 *** NOT GATED *** ./escape.fast.length:I64 slow.length:I64 default=8 bias.scale:F64 default=0.5 ``` Six of seven file intakes gate uniformly (Finding W2). **`sweep --list-axes` does not** — it exits 0 and prints a mangled, retired *wrapped* axis form `./escape.fast.length` for the open param only. The same on a `.` root: `sweep --list-axes` → `.fast.length:I64` (exit 0) while `register`/`--params` refuse. Pasting the leaked `./escape.fast.length` back as `--axis` refuses — so discovery emits a name the bind surface rejects. (Finding B1.) Prose note: `run` and `graph` prepend the full file path; `register`, `sweep --axis`, `introspect` do not — the core sentence is uniform, the prefix is not. (Finding SG1.) --- ## Example 3 — use-splice interplay (`c331_3*`) Registered patterns: `agree` (input `x`, SMA length open), `refute` (input `y`), `unnamedsm` (unnamed → `graph`, input `z`). ``` # A — splice agree, NO instance name: $ aura graph build < c331_3A_splice_named.ops.json # exit 0 aura: note: use "agree": agree -> 4f78a9f6e1f3… $ aura graph introspect --params c331_3A.bp.json agree.sma.length:I64 ← instance defaulted to authored name # B — splice unnamedsm TWICE, no instance names: $ aura graph build < c331_3B_two_unnamed.ops.json # exit 1 aura: note: use "graph": unnamedsm -> 25cdd4942f21… aura: note: use "graph": unnamedsm -> 25cdd4942f21… aura: op 3 (use): duplicate identifier "graph" ← collide, op-indexed # C — splice agree + refute, no instance names: $ aura graph build < c331_3C_two_named.ops.json # exit 0 $ aura graph introspect --params c331_3C.bp.json agree.sma.length:I64 refute.sma.length:I64 ← distinct names, no collision ``` Instance identifier defaults to the authored render name; two unnamed (`graph`) splices collide with an op-indexed `duplicate identifier "graph"`; distinct authored names dissolve the collision. Matches guide + glossary `blueprint label` entry exactly. (Finding W3.) --- ## Example 4 — discovery / docs parity (`c331_4_*`) `aura graph build --help` lists the name op last of the eleven: ``` {"op":"name","name":"ny_momentum"} set the composite's render name, at most once per script (default "graph" if omitted) ``` Consistent with the authoring guide's eleven-ops table (§1). Three distinct `--name`-ish concepts, each with distinct help phrasing: - op `name` → **render name** (keys `traces//`, use-splice instance default) - `aura graph register --name` → **registry label** ("Label the registered content id for `use` by name (#317)") - `aura sweep --name` → **family name** ("Family name (records to the registry…)") The glossary `blueprint label` entry separates render name from registry label explicitly. Distinction is learnable from the public docs alone, though a consumer must consult the glossary to fully disambiguate the three. (Finding W4.) --- ## Findings summary - W1 (working, axis 1): authored name → blueprint bytes + store doc + `traces//`; default `graph` collision observable (silent overwrite). - W2 (working, axis 2): op-route refusals op-indexed + specific; hand-edited bad root name gated uniformly on 6 of 7 file intakes. - W3 (working, axis 3): use-splice instance defaults to authored name; unnamed splices collide (op-indexed); named splices coexist. - W4 (working, axis 4): `graph build --help` lists the name op consistently with the guide; render-name vs registry-label distinction learnable. - B1 (BUG, axis 2): `sweep --list-axes` does not gate a bad root name (exit 0) and leaks a retired, non-bindable wrapped axis form (`./escape.fast.length`), breaking #328's `--params`/`--list-axes` line-identity and the every-discovered-name-is-verbatim-legal promise. - SG1 (spec_gap, axis 2): "uniform refusal prose" — `run`/`graph` prepend the file path, other seams don't; unclear whether "uniform" means the core sentence or byte-identical.