Files
Aura/fieldtests/composites-use/TRANSCRIPT.md
T
claude cb3330ceb5 fieldtest: composites-use — 4 examples, 1 bug / 1 friction / 3 spec-gap / 3 working
Source-blind per-cycle fieldtest of the #317 surface (register->label->
discover->use loop; ref forms + refusal UX; open patterns; sweep axes through
a spliced instance). Corpus under fieldtests/composites-use/ with TRANSCRIPT.md.

Working: the full authoring loop (W1), ref-form variety incl. ambiguous/
unknown-prefix and unknown-label refusals (W2), sweep --list-axes and a real
sweep through graph.<instance>.<node>.<param> plus splice-time bind (W3).

Findings, routed at close:
- B1 (reclassified: docs untruth, behaviour ratified): an open pattern whose
  input role names an archive column RUNS standalone — the harness binds
  roles by name, which is C26's design; the "running standalone refuses"
  claim was the wrong sentence, fixed in the follow-up docs commit and
  minuted on #317.
- S1: the run path's actual refusal trio (bias/tap gate, free knobs, role-
  column) vs the docs' bootstrap-gate story -> same docs commit + #339 note.
- F1: gang-on-instance-member refusal does not name the unsupported-rule ->
  evidence added to #339 item 1.
- S2: README still enumerated nine ops -> fixed in the follow-up commit.
- S3: the use-seam C29 gate is unreachable through today's CLI writes
  (register gates both input forms) -> ratified as a backstop, one line in
  C24.
- Orthogonal pre-existing observation (NOT #317): aura run --params did not
  close free knobs in the fieldtester's hands -> #340.

refs #317
2026-07-24 20:09:11 +02:00

6.2 KiB

Fieldtest transcript — cycle #317 (composites, the use op)

Verbatim command/output capture for the fieldtests/composites-use/ fixtures. Binary: target/release/aura built from HEAD 4a30222 (release profile). Project: ./lab (scaffolded with aura new lab; /runs gitignored). Commands using the store were run from inside lab/.

Example 1 — register → --name → discover → use by name → splice

$ aura graph build < cu_1_pattern_spread.ops.json
{... "input_roles":[{"name":"price","targets":[{"node":0,"slot":0},{"node":1,"slot":0}]}] ...}
# open pattern: input role "price" carries no "source":<kind> (contrast a source role)

$ aura graph introspect --params cu_1_pattern_spread.ops.json
fast.length:I64
slow.length:I64

$ aura graph introspect --unwired < cu_1_pattern_spread.ops.json
# (no output — the price input role feeds fast.series/slow.series, so no open interior slot)

# --- inside lab/ ---
$ aura graph register .../cu_1_pattern_spread.ops.json --name spread_xover
registered blueprint f61659aaa8dd1933c9e42f437f06be3ae346dd61569b5e013f07285e6fda03b1 (.../runs/blueprints/f61659....json)
label "spread_xover" -> f61659aaa8dd1933c9e42f437f06be3ae346dd61569b5e013f07285e6fda03b1

$ aura graph introspect --registered
spread_xover  f61659aaa8dd  open SMA-crossover spread pattern: fast minus slow over an injected price input role

$ aura graph build < cu_1_consumer.ops.json   > payload   2> echo
# stderr (echo): aura: note: use "xover": spread_xover -> f61659aaa8dd1933c9e42f437f06be3ae346dd61569b5e013f07285e6fda03b1
# stdout (payload): {... "nodes":[{"composite":{"name":"xover", ... spliced inline ...}}, {"primitive":{"type":"Bias"...}}] ...}

$ aura graph introspect --params cu_1_consumer.ops.json
xover.fast.length:I64
xover.slow.length:I64
bias.scale:F64

Example 2 — ref-form variety + refusal UX

Store contains labels ema_smoother (1c8edf24a1eb) and spread_xover (f61659aaa8dd), plus two unlabelled spread variants e6982f7d... and e8f04011... (both start with e).

$ aura graph register .../cu_2_docless.ops.json --name docless
aura: blueprint: composite `graph` carries no doc — a registered composite describes itself (C29); add a doc line (...) before register
# exit 1  (register gates doc-less at register; a doc-less entry never enters the store)

# by full content id  -> splices, echoes id
$ aura graph build < cu_2_ref_full_id.ops.json
aura: note: use "sp": e6982f7d...d55d82 -> e6982f7d...d55d82           (exit 0)

# by unique prefix "e69"  -> splices, echoes resolved id
$ aura graph build < cu_2_ref_prefix.ops.json
aura: note: use "sp": e69 -> e6982f7d...d55d82                         (exit 0)

# by ambiguous prefix "e"  -> refuses, enumerates candidates
$ aura graph build < cu_2_ref_ambiguous.ops.json
aura: op 2 (use "sp"): ambiguous id "e": candidates e6982f7d...d55d82, e8f04011...07fcf8   (exit 1)

# by unknown prefix "deadbeef"  -> refuses
$ aura graph build < cu_2_ref_unknown_prefix.ops.json
aura: op 2 (use "sp"): no registered blueprint matches content id "deadbeef"              (exit 1)

# by unknown label "nope"  -> refuses, enumerates labels
$ aura graph build < cu_2_ref_unknown_label.ops.json
aura: op 2 (use "sp"): no registered blueprint labeled "nope" — registered labels: ema_smoother, spread_xover   (exit 1)

Example 3 — running an open pattern standalone

Docs (authoring guide input row; glossary use (op)) say: "only running it standalone refuses (bootstrap's unbound-root-role gate)."

# (a) spread-exposing open pattern -> refuses on the run-SHAPE gate (not the role gate)
$ aura run spread_open.bp.json
aura: `aura run` needs either a `bias` output (a strategy) or ≥1 declared tap (a measurement); this blueprint exposes neither   (exit 1)

# (b) bias-exposing open pattern, params OPEN -> refuses on the OPEN-PARAMS gate
$ aura run open_bias.bp.json
aura: run requires a closed blueprint (no free parameters); 3 free knob(s) — bind them or use `aura sweep --axis`               (exit 2)
$ aura run open_bias.bp.json --params '[{"I64":2},{"I64":4},{"F64":0.5}]'
aura: run requires a closed blueprint (no free parameters); 3 free knob(s) — ...   (exit 2)   # --params did not close the knobs

# (c) bias-exposing open pattern, params BOUND, input role "price" OPEN -> RUNS CLEAN (docs say refuse)
$ aura run open_bias_bound.bp.json          # from cu_3_open_bias_bound.ops.json
{"manifest":{...,"params":[],"defaults":[["graph.fast.length",{"I64":2}],...]},"metrics":{"total_pips":0.3418...}}   (exit 0)

# (d) same, but input role named "quote" (not a column name) -> refuses on the ROLE-COLUMN gate
$ aura run altrole.bp.json
aura: input role "quote" of strategy "graph" binds to no archive column — bindable columns: open, high, low, close (alias: price), spread, volume; or bind it explicitly in the campaign data.bindings block   (exit 1)

Example 4 — sweep integration + gang refusal + happy-path run

$ aura sweep cu_1_consumer.bp.json --list-axes
graph.xover.fast.length:I64
graph.xover.slow.length:I64
graph.bias.scale:F64

$ aura sweep cu_1_consumer.bp.json --axis graph.xover.fast.length=2,3 \
    --axis graph.xover.slow.length=6 --axis graph.bias.scale=0.5 --name cu4_sweep
{"family_id":"cu4_sweep-0","report":{"manifest":{...,"params":[["graph.xover.fast.length",{"I64":2}],["graph.xover.slow.length",{"I64":6}],...]}}}
{"family_id":"cu4_sweep-0","report":{"manifest":{...,"params":[["graph.xover.fast.length",{"I64":3}],...]}}}
# exit 0, 2 members — spliced-instance params sweep through the nesting

# gang a spliced instance's member path -> refuses (documented), but message frames it as a missing param
$ aura graph build < cu_4_gang_instance_member.ops.json
aura: note: use "xover": spread_xover -> f61659...
aura: op 6 (gang): node xover has no param "fast.length"     (exit 1)

# happy path: use + splice-time bind -> closed blueprint -> run
$ aura graph build < cu_1_consumer_bound.ops.json > closed.bp.json
$ aura graph introspect --params cu_1_consumer_bound.ops.json     # (empty = closed)
$ aura run closed.bp.json
{"manifest":{...,"params":[],"defaults":[["graph.xover.fast.length",{"I64":2}],...]},"metrics":{...}}   (exit 0)
$ aura run closed.bp.json --real GER40
{"manifest":{...}}   (exit 0)