diff --git a/fieldtests/cycle-319-sugar-retirement/TRANSCRIPT.md b/fieldtests/cycle-319-sugar-retirement/TRANSCRIPT.md new file mode 100644 index 0000000..0deac46 --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/TRANSCRIPT.md @@ -0,0 +1,179 @@ +# Fieldtest transcript — cycle 319 (sugar retirement, one `exec` verb) + +Binary under test: `target/release/aura`, built from this worktree +(`cargo build --release --workspace`, HEAD = `1476990`, tree dirty only by +this corpus). Every command below was run from inside the scaffolded project +`c319lab/` unless the prompt says otherwise. Public-interface sources used: +`README.md`, `docs/authoring-guide.md`, `docs/project-layout.md`, +`docs/design/INDEX.md` + `contracts/c14-headless-two-faces.md`, `aura --help`, +the scaffolded `c319lab/CLAUDE.md`. No implementation source was read. + +## Persona + +A downstream consumer who last used aura when the research verbs were +`run / sweep / walkforward / mc / generalize`, returning to a fresh project. + +## Files + +| file | what it is | +|---|---| +| `c319lab/` | project scaffolded with `aura new c319lab` (its `runs/` store is git-ignored by the scaffold's own `.gitignore`) | +| `c319_1_spread_tap.ops.json` | op-script: SMA crossover with a declared `spread` tap (canonical authoring form) | +| `c319_1b_open.ops.json` | same, both SMA lengths left open (free knobs) | +| `c319_2b_zero_bind.ops.json` | same, `fast.length` bound to `0` — the out-of-domain value authored, not overridden | +| `c319_2_targets_*.json` | malformed / wrong-class `exec` targets | +| `c319lab/blueprints/c319_3_process_sweep.json` | process document: `std::sweep` argmax on `sqn` | +| `c319lab/blueprints/c319_3_campaign_sweep.json` | campaign document: GER40, 1 month, 3 axes / 4 points | +| `c319lab/blueprints/c319_4_campaign_override.json` | same with only 2 axes, so `bias.scale` stays a bound default (override target) | +| `c319lab/blueprints/c319_4b_campaign_zerolen.json` | `fast.length` axis = `[0]` (out-of-domain via the campaign leg) | +| `c319lab/blueprints/c319_5_process_wf.json` | process: `std::sweep` → `std::walk_forward` | +| `c319lab/blueprints/c319_5_campaign_wf_flat.json` | campaign with `fast.length == slow.length` → flat spread → zero trades | +| `c319_*.txt` / `c319_*.err` | verbatim captured runs | + +## 1 — Coming back to a retired verb (axis 3) + +``` +$ aura new c319lab +created project "c319lab" (data-only; attach native nodes later with `aura nodes new`) + +$ aura run blueprints/signal.json +error: unrecognized subcommand 'run' + + tip: a similar subcommand exists: 'runs' +EXIT=2 +``` + +(full set in `c319_3_retired_verbs.err`: `sweep`, `walkforward`, `mc`, +`generalize` all give the bare clap "unrecognized subcommand", no tip; `run` +gets the `runs` tip.) + +Recovery took one `aura --help`: its about-text names `exec` as the one +executor over both document classes and points at `graph introspect --params` +for axes. The scaffolded `c319lab/CLAUDE.md` teaches the same three lines. +Neither the retired-verb refusal nor anything else names `exec` at the point +of failure. + +## 2 — Blueprint leg: smoke run, taps, overrides (axes 1, 2, 4) + +`c319_1_tap_loop.txt` — build from an op-script, list the fold roster, run +with `--tap spread=record`, run again under a different `--override`. +`c319_2_override_family.txt` — the whole override refusal family on both legs. + +Highlights (verbatim): + +``` +$ aura exec blueprints/signal.json --override fast.length=8 + → manifest.params=[['fast.length', {'I64': 8}]], defaults keep the rest EXIT=0 +$ aura exec blueprints/signal.json --override fast.length=8 --override fast.length=9 +aura: exec: --override names path "fast.length" twice EXIT=2 +$ aura exec blueprints/signal.json --override nosuch.param=3 +aura: axis nosuch.param: names no param of this blueprint (open or bound) — see `aura graph introspect --params ` EXIT=1 +$ aura exec blueprints/signal.json --override fast.length +aura: exec: --override expects NODE.PARAM=VALUE, got `fast.length` EXIT=2 +$ aura exec blueprints/signal.json --override fast.length=abc +aura: exec: --override expects NODE.PARAM=VALUE, got `fast.length=abc` EXIT=2 +$ aura exec blueprints/signal.json --override fast.length=1.5 +aura: this blueprint does not compile to a runnable harness: ParamKindMismatch { slot: 0, expected: I64, got: F64 } EXIT=1 +$ aura exec blueprints/signal.json --override fast.length=0 +thread 'main' panicked at crates/aura-std/src/sma.rs:46:9: SMA length must be >= 1 EXIT=101 +$ aura exec blueprints/signal.json --override fast.length=-3 +thread 'main' panicked at .../alloc/src/raw_vec/mod.rs:28:5: capacity overflow EXIT=101 +$ aura exec blueprints/signal.json --override c319lab_signal.fast.length=1 +thread 'main' panicked at crates/aura-cli/src/main.rs:1160:38: override set derived from these exact overrides EXIT=101 +``` + +The same out-of-domain value authored into the blueprint (`c319_2b_zero_bind.ops.json`, +`bind {"length":{"I64":0}}`, no `--override` at all) panics identically — so +the containment gap is the single-run leg's, not `--override`'s parser. + +Open blueprint, and whether `--override` can close one: + +``` +$ aura exec blueprints/c319_1b_open.bp.json +aura: run requires a closed blueprint (no free parameters); 2 free knob(s) — bind them in the +blueprint or vary them as campaign axes; a single bound knob can be overridden with --override +EXIT=2 +$ aura exec blueprints/c319_1b_open.bp.json --override fast.length=3 --override slow.length=8 +(same message) EXIT=2 +``` + +Tap loop: `--tap spread=record` persisted `runs/traces/c319_spread/spread.json` +(11 warm rows) + `index.json` carrying the run manifest; `aura chart c319_spread` +emitted HTML. `--tap spread=median` → `aura: unknown fold 'median' — available: +count, first, last, max, mean, min, record, sum` (exit 1); `--tap spread` → +`aura: --tap expects TAP=FOLD, got "spread"` (exit 2); a tap name the blueprint +does not declare → `aura: the tap plan names 'spread', but the blueprint declares +no such tap — declared taps: ` (exit 1, trailing empty list). + +A second `exec` of the same blueprint under a different `--override` wrote into +the same `runs/traces/c319_spread/` and replaced the first run's series; no +note, no second directory. + +## 3 — Campaign leg: axis discovery → running sweep family (axes 2, 3) + +`c319_3_sweep_family.txt`. Register blueprint + process, author the campaign +document from `docs/authoring-guide.md` §3, validate (three tiers all green), +`aura exec`: 4 members over GER40 2024-09-01…2024-10-01 (1661–2581 trades each) +plus a `selection_report`, `aura: campaign run N recorded: 1 cells`, exit 0. + +Campaign-leg overrides (`c319_2_override_family.txt`, second half): a bound +param not on an axis is accepted (exit 0); a declared axis collides +(`aura: exec: --override \`fast.length\` collides with a declared axis of the +campaign; an override overrides a bound value, never an axis`, exit 2); an +unknown path and a kind mismatch speak the campaign's referential prose (exit 1); +a duplicate path and a non-scalar value speak the shared lexer (exit 2). The +retired wrapped form is refused here with the documented translation pointer: + +``` +$ aura exec blueprints/c319_4_campaign_override.json --override c319lab_signal.bias.scale=0.25 +aura: campaign references do not resolve: + strategy 7987bec1…: axis "c319lab_signal.bias.scale" is not in the param space; + axis names are raw node.param paths — did you mean "bias.scale"? EXIT=1 +``` + +— the same token that panics on the blueprint leg (see §2). + +## 4 — Target classification (axis 1) + +`c319_2_target_classes.err`, exit codes verified individually: + +| target | stderr | exit | +|---|---|---| +| file, not JSON | `aura: exec: : target file is not valid JSON: key must be a string at line 1 column 3` | 2 | +| op-script array (valid JSON) | `aura: : blueprint document is not valid JSON: invalid type: map, expected u32 at line 2 column 2` | 2 | +| `{}` | `aura: : blueprint document is not valid JSON: missing field \`format_version\`` | 2 | +| `"kind":"campain"` typo | `aura: campaign document: the "kind" key must be "campaign"` | 1 | +| a **process** document | `aura: campaign document: the "kind" key must be "campaign"` | 1 | +| missing file / directory / bare name | `aura: '' is neither a readable .json file nor a 64-hex content id` | 1 | +| id prefix `3ca5ca90` | same as above | 1 | +| campaign *name* | same as above | 1 | +| unregistered 64-hex | `aura: no campaign in the project store` | 1 | +| a registered **blueprint's** id | `aura: no campaign in the project store` | 1 | +| registered campaign id | runs | 0 | + +## 5 — Walk-forward zero-trade note on the campaign path (axis 4) + +`c319_4_walkforward_zero_trade.err`. `fast.length == slow.length == 4` makes the +spread identically zero, so the bias never leaves 0: + +``` +$ aura exec blueprints/c319_5_campaign_wf_flat.json +aura: note: all 2 walk-forward windows recorded zero trades +aura: campaign run N recorded: 1 cells +EXIT=0 +``` + +Class marker, exit code and "a null result is a valid research result" all as +C14 describes. + +## 6 — Per-cell fault containment, for contrast + +`c319_4b_campaign_zerolen.json` puts the same out-of-domain `0` on a campaign +axis: + +``` +aura: warning: cell (7987bec1…, GER40, [1725148800000, 1727740800000]) failed at stage 0: +a member panicked: SMA length must be >= 1 — recorded, campaign continues +aura: campaign run N recorded: 1 cells, 1 failed (GER40: panic) +EXIT=3 +``` diff --git a/fieldtests/cycle-319-sugar-retirement/c319_1_spread_tap.ops.json b/fieldtests/cycle-319-sugar-retirement/c319_1_spread_tap.ops.json new file mode 100644 index 0000000..fbf6fc7 --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319_1_spread_tap.ops.json @@ -0,0 +1,15 @@ +[ + {"op": "name", "name": "c319_spread"}, + {"op": "doc", "text": "fast/slow SMA spread, tapped before the bias clamp"}, + {"op": "source", "role": "price", "kind": "F64"}, + {"op": "add", "type": "SMA", "name": "fast", "bind": {"length": {"I64": 3}}}, + {"op": "add", "type": "SMA", "name": "slow", "bind": {"length": {"I64": 8}}}, + {"op": "feed", "role": "price", "into": ["fast.series", "slow.series"]}, + {"op": "add", "type": "Sub", "name": "sub"}, + {"op": "connect", "from": "fast.value", "to": "sub.lhs"}, + {"op": "connect", "from": "slow.value", "to": "sub.rhs"}, + {"op": "add", "type": "Bias", "name": "bias", "bind": {"scale": {"F64": 0.5}}}, + {"op": "connect", "from": "sub.value", "to": "bias.signal"}, + {"op": "tap", "from": "sub.value", "as": "spread"}, + {"op": "expose", "from": "bias.bias", "as": "bias"} +] diff --git a/fieldtests/cycle-319-sugar-retirement/c319_1_tap_loop.txt b/fieldtests/cycle-319-sugar-retirement/c319_1_tap_loop.txt new file mode 100644 index 0000000..798cb23 --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319_1_tap_loop.txt @@ -0,0 +1,36 @@ +$ aura graph build < ../c319_1_spread_tap.ops.json > blueprints/c319_1_spread_tap.bp.json +EXIT=0 + +$ aura graph introspect --folds +count — number of warm rows (any kind; i64 row); one row at the last warm ts +first — first warm value, at its own timestamp (any kind; kind-preserving row) +last — last warm value, at its own timestamp (any kind; kind-preserving row) +max — maximum of the series (f64 taps; f64 row); one row at the last warm ts +mean — arithmetic mean of the series (f64 taps; f64 row); one row at the last warm ts +min — minimum of the series (f64 taps; f64 row); one row at the last warm ts +record — persist the full series, lossless, at constant memory (any kind) +sum — sum of the series (f64 taps; f64 row); one row at the last warm ts + +$ aura exec blueprints/c319_1_spread_tap.bp.json --override fast.length=2 --tap spread=record +EXIT=0 +runs/traces/c319_spread/spread.json: +{"tap":"spread","kinds":["F64"],"ts":[8,9,10,11,12,13,14,15,16,17,18],"columns":[[0.002650000000000041,-0.0002249999999999197,-0.0027250000000000885,-0.004237499999999894,-0.004124999999999934,-0.0023 + +$ aura exec blueprints/c319_1_spread_tap.bp.json --override fast.length=6 --tap spread=record # second override, same blueprint +EXIT=0 +runs/traces/ now holds: + c319_spread +runs/traces/c319_spread/spread.json (run A's series is gone): +{"tap":"spread","kinds":["F64"],"ts":[8,9,10,11,12,13,14,15,16,17,18],"columns":[[0.001383333333333292,0.0011750000000001481,0.0006749999999999812,-0.00010416666666679397,-0.001091666666666491,-0.0015 + +$ aura exec blueprints/c319_1_spread_tap.bp.json --tap spread=median +EXIT=1 +aura: unknown fold 'median' — available: count, first, last, max, mean, min, record, sum + +$ aura exec blueprints/c319_1_spread_tap.bp.json --tap spread +EXIT=2 +aura: --tap expects TAP=FOLD, got "spread" + +$ aura exec blueprints/signal.json --tap spread=record # blueprint declares no taps +EXIT=1 +aura: the tap plan names 'spread', but the blueprint declares no such tap — declared taps: diff --git a/fieldtests/cycle-319-sugar-retirement/c319_1b_open.ops.json b/fieldtests/cycle-319-sugar-retirement/c319_1b_open.ops.json new file mode 100644 index 0000000..a8bd046 --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319_1b_open.ops.json @@ -0,0 +1,15 @@ +[ + {"op": "name", "name": "c319_open"}, + {"op": "doc", "text": "fast/slow SMA spread, tapped before the bias clamp"}, + {"op": "source", "role": "price", "kind": "F64"}, + {"op": "add", "type": "SMA", "name": "fast"}, + {"op": "add", "type": "SMA", "name": "slow"}, + {"op": "feed", "role": "price", "into": ["fast.series", "slow.series"]}, + {"op": "add", "type": "Sub", "name": "sub"}, + {"op": "connect", "from": "fast.value", "to": "sub.lhs"}, + {"op": "connect", "from": "slow.value", "to": "sub.rhs"}, + {"op": "add", "type": "Bias", "name": "bias", "bind": {"scale": {"F64": 0.5}}}, + {"op": "connect", "from": "sub.value", "to": "bias.signal"}, + {"op": "tap", "from": "sub.value", "as": "spread"}, + {"op": "expose", "from": "bias.bias", "as": "bias"} +] diff --git a/fieldtests/cycle-319-sugar-retirement/c319_2_override_family.txt b/fieldtests/cycle-319-sugar-retirement/c319_2_override_family.txt new file mode 100644 index 0000000..96dd3f8 --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319_2_override_family.txt @@ -0,0 +1,69 @@ +== blueprint leg (blueprints/signal.json; fast.length:I64=2 slow.length:I64=4 bias.scale:F64=0.5) == +$ aura exec blueprints/signal.json --override fast.length=8 +(stdout run record; manifest.params=[['fast.length', {'I64': 8}]]) +EXIT=0 + +$ aura exec blueprints/signal.json --override fast.length=8 --override bias.scale=0.25 +(stdout run record; manifest.params=[['fast.length', {'I64': 8}], ['bias.scale', {'F64': 0.25}]]) +EXIT=0 + +$ aura exec blueprints/signal.json --override fast.length=8 --override fast.length=9 +aura: exec: --override names path "fast.length" twice +EXIT=2 + +$ aura exec blueprints/signal.json --override nosuch.param=3 +aura: axis nosuch.param: names no param of this blueprint (open or bound) — see `aura graph introspect --params ` +EXIT=1 + +$ aura exec blueprints/signal.json --override bias.scal=0.25 +aura: axis bias.scal: names no param of this blueprint (open or bound) — see `aura graph introspect --params ` +EXIT=1 + +$ aura exec blueprints/signal.json --override fast.length +aura: exec: --override expects NODE.PARAM=VALUE, got `fast.length` +EXIT=2 + +$ aura exec blueprints/signal.json --override fast.length=1.5 +aura: this blueprint does not compile to a runnable harness: ParamKindMismatch { slot: 0, expected: I64, got: F64 } +EXIT=1 + +$ aura exec blueprints/signal.json --override bias.scale=1 +aura: this blueprint does not compile to a runnable harness: ParamKindMismatch { slot: 0, expected: F64, got: I64 } +EXIT=1 + +$ aura exec blueprints/signal.json --override fast.length=abc +aura: exec: --override expects NODE.PARAM=VALUE, got `fast.length=abc` +EXIT=2 + +== campaign leg (blueprints/c319_4_campaign_override.json; declared axes fast.length, slow.length) == +$ aura exec blueprints/c319_4_campaign_override.json --override bias.scale=0.25 +aura: campaign run 1 recorded: 1 cells +EXIT=0 + +$ aura exec blueprints/c319_4_campaign_override.json --override fast.length=3 +aura: exec: --override `fast.length` collides with a declared axis of the campaign; an override overrides a bound value, never an axis +EXIT=2 + +$ aura exec blueprints/c319_4_campaign_override.json --override nosuch.param=3 +aura: campaign references do not resolve: + strategy 7987bec19abfaccf8b98075511a05edcca5edce86755b781d3328cd75a7b4911: axis "nosuch.param" is not in the param space +EXIT=1 + +$ aura exec blueprints/c319_4_campaign_override.json --override bias.scal=0.25 +aura: campaign references do not resolve: + strategy 7987bec19abfaccf8b98075511a05edcca5edce86755b781d3328cd75a7b4911: axis "bias.scal" is not in the param space +EXIT=1 + +$ aura exec blueprints/c319_4_campaign_override.json --override bias.scale=0.25 --override bias.scale=0.75 +aura: exec: --override names path "bias.scale" twice +EXIT=2 + +$ aura exec blueprints/c319_4_campaign_override.json --override bias.scale=1 +aura: campaign references do not resolve: + strategy 7987bec19abfaccf8b98075511a05edcca5edce86755b781d3328cd75a7b4911: axis "bias.scale" declares a kind that is not the param's kind +EXIT=1 + +$ aura exec blueprints/c319_4_campaign_override.json --override bias.scale=abc +aura: exec: --override expects NODE.PARAM=VALUE, got `bias.scale=abc` +EXIT=2 + diff --git a/fieldtests/cycle-319-sugar-retirement/c319_2_override_panic.err b/fieldtests/cycle-319-sugar-retirement/c319_2_override_panic.err new file mode 100644 index 0000000..dae2345 --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319_2_override_panic.err @@ -0,0 +1,18 @@ +$ aura exec blueprints/signal.json --override fast.length=0 + +thread 'main' (2726290) panicked at crates/aura-std/src/sma.rs:46:9: +SMA length must be >= 1 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +EXIT=101 + +$ aura exec blueprints/signal.json --override fast.length=-3 + +thread 'main' (2726295) panicked at /rustc/4a4ef493e3a1488c6e321570238084b38948f6db/library/alloc/src/raw_vec/mod.rs:28:5: +capacity overflow +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +EXIT=101 + +$ aura exec blueprints/c319_4b_campaign_zerolen.json # same value via a campaign axis +aura: warning: cell (7987bec19abfaccf8b98075511a05edcca5edce86755b781d3328cd75a7b4911, GER40, [1725148800000, 1727740800000]) failed at stage 0: a member panicked: SMA length must be >= 1 — recorded, campaign continues +aura: campaign run 1 recorded: 1 cells, 1 failed (GER40: panic) +EXIT=3 diff --git a/fieldtests/cycle-319-sugar-retirement/c319_2_target_classes.err b/fieldtests/cycle-319-sugar-retirement/c319_2_target_classes.err new file mode 100644 index 0000000..1d14e21 --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319_2_target_classes.err @@ -0,0 +1,44 @@ +$ aura exec ../c319_2_targets_notjson.json +aura: exec: ../c319_2_targets_notjson.json: target file is not valid JSON: key must be a string at line 1 column 3 +EXIT=2 + +$ aura exec ../c319_2_targets_opscript.json +aura: ../c319_2_targets_opscript.json: blueprint document is not valid JSON: invalid type: map, expected u32 at line 2 column 2 +EXIT=2 + +$ aura exec ../c319_2_targets_emptyobj.json +aura: ../c319_2_targets_emptyobj.json: blueprint document is not valid JSON: missing field `format_version` at line 1 column 2 +EXIT=2 + +$ aura exec ../c319_2_targets_kindtypo.json +aura: campaign document: the "kind" key must be "campaign" +EXIT=1 + +$ aura exec blueprints/c319_5_process_wf.json +aura: campaign document: the "kind" key must be "campaign" +EXIT=1 + +$ aura exec blueprints/nosuch.json +aura: 'blueprints/nosuch.json' is neither a readable .json file nor a 64-hex content id +EXIT=1 + +$ aura exec blueprints +aura: 'blueprints' is neither a readable .json file nor a 64-hex content id +EXIT=1 + +$ aura exec 3ca5ca90 +aura: '3ca5ca90' is neither a readable .json file nor a 64-hex content id +EXIT=1 + +$ aura exec c319-ger40-smacross-sweep +aura: 'c319-ger40-smacross-sweep' is neither a readable .json file nor a 64-hex content id +EXIT=1 + +$ aura exec 7987bec19abfaccf8b98075511a05edcca5edce86755b781d3328cd75a7b4911 +aura: no campaign 7987bec19abfaccf8b98075511a05edcca5edce86755b781d3328cd75a7b4911 in the project store +EXIT=1 + +$ aura exec blueprints/c319_1b_open.bp.json +aura: run requires a closed blueprint (no free parameters); 2 free knob(s) — bind them in the blueprint or vary them as campaign axes; a single bound knob can be overridden with --override +EXIT=2 + diff --git a/fieldtests/cycle-319-sugar-retirement/c319_2_targets_emptyobj.json b/fieldtests/cycle-319-sugar-retirement/c319_2_targets_emptyobj.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319_2_targets_emptyobj.json @@ -0,0 +1 @@ +{} diff --git a/fieldtests/cycle-319-sugar-retirement/c319_2_targets_kindtypo.json b/fieldtests/cycle-319-sugar-retirement/c319_2_targets_kindtypo.json new file mode 100644 index 0000000..b61d379 --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319_2_targets_kindtypo.json @@ -0,0 +1 @@ +{"format_version": 1, "kind": "campain", "name": "typo-kind"} diff --git a/fieldtests/cycle-319-sugar-retirement/c319_2_targets_notjson.json b/fieldtests/cycle-319-sugar-retirement/c319_2_targets_notjson.json new file mode 100644 index 0000000..942120e --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319_2_targets_notjson.json @@ -0,0 +1 @@ +{ this is not json at all, diff --git a/fieldtests/cycle-319-sugar-retirement/c319_2_targets_opscript.json b/fieldtests/cycle-319-sugar-retirement/c319_2_targets_opscript.json new file mode 100644 index 0000000..d7732af --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319_2_targets_opscript.json @@ -0,0 +1,12 @@ +[ + {"op": "source", "role": "price", "kind": "F64"}, + {"op": "add", "type": "SMA", "name": "fast", "bind": {"length": {"I64": 2}}}, + {"op": "add", "type": "SMA", "name": "slow", "bind": {"length": {"I64": 4}}}, + {"op": "feed", "role": "price", "into": ["fast.series", "slow.series"]}, + {"op": "add", "type": "Sub", "name": "sub"}, + {"op": "connect", "from": "fast.value", "to": "sub.lhs"}, + {"op": "connect", "from": "slow.value", "to": "sub.rhs"}, + {"op": "add", "type": "Bias", "name": "bias", "bind": {"scale": {"F64": 0.5}}}, + {"op": "connect", "from": "sub.value", "to": "bias.signal"}, + {"op": "expose", "from": "bias.bias", "as": "bias"} +] diff --git a/fieldtests/cycle-319-sugar-retirement/c319_2_wrapped_path_panic.err b/fieldtests/cycle-319-sugar-retirement/c319_2_wrapped_path_panic.err new file mode 100644 index 0000000..043ca2a --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319_2_wrapped_path_panic.err @@ -0,0 +1,11 @@ +$ aura exec blueprints/signal.json --override c319lab_signal.bias.scale=0.25 + +thread 'main' (2726331) panicked at crates/aura-cli/src/main.rs:1160:38: +override set derived from these exact overrides +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +EXIT=101 + +$ aura exec blueprints/c319_4_campaign_override.json --override c319lab_signal.bias.scale=0.25 # same token, campaign leg +aura: campaign references do not resolve: + strategy 7987bec19abfaccf8b98075511a05edcca5edce86755b781d3328cd75a7b4911: axis "c319lab_signal.bias.scale" is not in the param space; axis names are raw node.param paths — did you mean "bias.scale"? +EXIT=1 diff --git a/fieldtests/cycle-319-sugar-retirement/c319_2b_zero_bind.ops.json b/fieldtests/cycle-319-sugar-retirement/c319_2b_zero_bind.ops.json new file mode 100644 index 0000000..5796fb5 --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319_2b_zero_bind.ops.json @@ -0,0 +1,15 @@ +[ + {"op": "name", "name": "c319_zero"}, + {"op": "doc", "text": "fast/slow SMA spread, tapped before the bias clamp"}, + {"op": "source", "role": "price", "kind": "F64"}, + {"op": "add", "type": "SMA", "name": "fast", "bind": {"length": {"I64": 0}}}, + {"op": "add", "type": "SMA", "name": "slow", "bind": {"length": {"I64": 8}}}, + {"op": "feed", "role": "price", "into": ["fast.series", "slow.series"]}, + {"op": "add", "type": "Sub", "name": "sub"}, + {"op": "connect", "from": "fast.value", "to": "sub.lhs"}, + {"op": "connect", "from": "slow.value", "to": "sub.rhs"}, + {"op": "add", "type": "Bias", "name": "bias", "bind": {"scale": {"F64": 0.5}}}, + {"op": "connect", "from": "sub.value", "to": "bias.signal"}, + {"op": "tap", "from": "sub.value", "as": "spread"}, + {"op": "expose", "from": "bias.bias", "as": "bias"} +] diff --git a/fieldtests/cycle-319-sugar-retirement/c319_3_retired_verbs.err b/fieldtests/cycle-319-sugar-retirement/c319_3_retired_verbs.err new file mode 100644 index 0000000..0c09da8 --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319_3_retired_verbs.err @@ -0,0 +1,35 @@ +$ aura run blueprints/signal.json +error: unrecognized subcommand 'run' + + tip: a similar subcommand exists: 'runs' + +EXIT=2 + +$ aura sweep blueprints/signal.json +error: unrecognized subcommand 'sweep' + +Usage: aura [OPTIONS] + +EXIT=2 + +$ aura walkforward blueprints/signal.json +error: unrecognized subcommand 'walkforward' + +Usage: aura [OPTIONS] + +EXIT=2 + +$ aura mc blueprints/signal.json +error: unrecognized subcommand 'mc' + +Usage: aura [OPTIONS] + +EXIT=2 + +$ aura generalize blueprints/signal.json +error: unrecognized subcommand 'generalize' + +Usage: aura [OPTIONS] + +EXIT=2 + diff --git a/fieldtests/cycle-319-sugar-retirement/c319_3_sweep_family.txt b/fieldtests/cycle-319-sugar-retirement/c319_3_sweep_family.txt new file mode 100644 index 0000000..0ccc09c --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319_3_sweep_family.txt @@ -0,0 +1,24 @@ +$ aura graph introspect --params blueprints/signal.json +fast.length:I64 default=2 +slow.length:I64 default=4 +bias.scale:F64 default=0.5 + +$ aura graph register blueprints/signal.json +registered blueprint 7987bec19abfaccf8b98075511a05edcca5edce86755b781d3328cd75a7b4911 (/home/brummel/dev/aura/.claude/worktrees/issue-319-sugar-retirement/fieldtests/cycle-319-sugar-retirement/c319lab/runs/blueprints/7987bec19abfaccf8b98075511a05edcca5edce86755b781d3328cd75a7b4911.json) + +$ aura process register blueprints/c319_3_process_sweep.json +registered process 954e735fc824ac74cceaaa6cbef8f8706a2fdaef3979ffb53cab854f0e3ca43b (/home/brummel/dev/aura/.claude/worktrees/issue-319-sugar-retirement/fieldtests/cycle-319-sugar-retirement/c319lab/runs/processes/954e735fc824ac74cceaaa6cbef8f8706a2fdaef3979ffb53cab854f0e3ca43b.json) + +$ aura campaign validate blueprints/c319_3_campaign_sweep.json +campaign document valid (intrinsic): 1 strategy(ies), 3 axes (4 points), 1 instrument(s), 1 window(s), 1 regime(s) (default) — 1 cell(s) +campaign document valid (referential): all references resolve, axes are in the param space +campaign document valid (executable): pipeline shape and static guards pass + +$ aura exec blueprints/c319_3_campaign_sweep.json # stderr + member summary +aura: campaign run 2 recorded: 1 cells + member {'fast.length': 2, 'slow.length': 16} n_trades=2581 exp_r=0.0019 sqn=0.0515 + member {'fast.length': 2, 'slow.length': 32} n_trades=1869 exp_r=-0.0433 sqn=-0.8164 + member {'fast.length': 4, 'slow.length': 16} n_trades=2388 exp_r=-0.0219 sqn=-0.5449 + member {'fast.length': 4, 'slow.length': 32} n_trades=1661 exp_r=-0.0132 sqn=-0.2080 + selection: std::sweep winner_ordinal=0 [['bias.scale', {'F64': 0.5}], ['fast.length', {'I64': 2}], ['slow.length', {'I64': 16}]] +EXIT=0 diff --git a/fieldtests/cycle-319-sugar-retirement/c319_4_walkforward_zero_trade.err b/fieldtests/cycle-319-sugar-retirement/c319_4_walkforward_zero_trade.err new file mode 100644 index 0000000..450c71b --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319_4_walkforward_zero_trade.err @@ -0,0 +1,4 @@ +$ aura exec blueprints/c319_5_campaign_wf_flat.json +aura: note: all 2 walk-forward windows recorded zero trades +aura: campaign run 1 recorded: 1 cells +EXIT=0 diff --git a/fieldtests/cycle-319-sugar-retirement/c319lab/.gitignore b/fieldtests/cycle-319-sugar-retirement/c319lab/.gitignore new file mode 100644 index 0000000..306cbf0 --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319lab/.gitignore @@ -0,0 +1 @@ +/runs diff --git a/fieldtests/cycle-319-sugar-retirement/c319lab/Aura.toml b/fieldtests/cycle-319-sugar-retirement/c319lab/Aura.toml new file mode 100644 index 0000000..d45dade --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319lab/Aura.toml @@ -0,0 +1,4 @@ +# Static project context only (C17); paths only. +[paths] +runs = "runs" +# data = "/path/to/archive" # the recorded-data root; defaults to the built-in path diff --git a/fieldtests/cycle-319-sugar-retirement/c319lab/CLAUDE.md b/fieldtests/cycle-319-sugar-retirement/c319lab/CLAUDE.md new file mode 100644 index 0000000..72b7d48 --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319lab/CLAUDE.md @@ -0,0 +1,24 @@ +# c319lab — an aura research project (data-only) + +This directory is an aura project: blueprints + research documents over the +std vocabulary, anchored by `Aura.toml`. There is no crate and no build step. + +- Run: `aura exec blueprints/signal.json` (single smoke run, synthetic stream + — the starter is closed; all params bound; bound values are defaults — + `--override NODE.PARAM=VALUE` may override one for this run (#246)) +- Campaign: `aura exec ` executes a registered campaign + document (file or content id) — the multi-cell/axis surface +- Axes: `aura graph introspect --params blueprints/signal.json` lists the + open + bound-overridable axes, RAW `.` names (#328) +- Native nodes: when the project needs its first project-specific node, + `aura nodes new ` scaffolds a node crate beside this project and + attaches it via `[nodes]` in `Aura.toml` (build it with `cargo build`). +- Topology is data (`blueprints/*.json`); results land in `runs/`. +- Execution model: a strategy emits a bias in [-1,+1] per cycle, held as the + continuously-tracked target position; a protective stop defines the risk + unit R, and quality metrics are R-based. Entry signals become held state + via the signal-side latch/edge-pulse idiom (see + `aura graph introspect --vocabulary`). +- Data plane: process/campaign documents are authored directly with + `aura process` / `aura campaign`, growing one from a bare `{}` via + `aura campaign introspect --unwired`. diff --git a/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_1_spread_tap.bp.json b/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_1_spread_tap.bp.json new file mode 100644 index 0000000..ffc8e18 --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_1_spread_tap.bp.json @@ -0,0 +1 @@ +{"format_version":1,"blueprint":{"name":"c319_spread","doc":"fast/slow SMA spread, tapped before the bias clamp","nodes":[{"primitive":{"type":"SMA","name":"fast","bound":[{"pos":0,"name":"length","kind":"I64","value":{"I64":3}}]}},{"primitive":{"type":"SMA","name":"slow","bound":[{"pos":0,"name":"length","kind":"I64","value":{"I64":8}}]}},{"primitive":{"type":"Sub","name":"sub"}},{"primitive":{"type":"Bias","name":"bias","bound":[{"pos":0,"name":"scale","kind":"F64","value":{"F64":0.5}}]}}],"edges":[{"from":0,"to":2,"slot":0,"from_field":0},{"from":1,"to":2,"slot":1,"from_field":0},{"from":2,"to":3,"slot":0,"from_field":0}],"input_roles":[{"name":"price","targets":[{"node":0,"slot":0},{"node":1,"slot":0}],"source":"F64"}],"output":[{"node":3,"field":0,"name":"bias"}],"taps":[{"name":"spread","from":{"node":2,"field":0}}]}} \ No newline at end of file diff --git a/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_1b_open.bp.json b/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_1b_open.bp.json new file mode 100644 index 0000000..e660170 --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_1b_open.bp.json @@ -0,0 +1 @@ +{"format_version":1,"blueprint":{"name":"c319_open","doc":"fast/slow SMA spread, tapped before the bias clamp","nodes":[{"primitive":{"type":"SMA","name":"fast"}},{"primitive":{"type":"SMA","name":"slow"}},{"primitive":{"type":"Sub","name":"sub"}},{"primitive":{"type":"Bias","name":"bias","bound":[{"pos":0,"name":"scale","kind":"F64","value":{"F64":0.5}}]}}],"edges":[{"from":0,"to":2,"slot":0,"from_field":0},{"from":1,"to":2,"slot":1,"from_field":0},{"from":2,"to":3,"slot":0,"from_field":0}],"input_roles":[{"name":"price","targets":[{"node":0,"slot":0},{"node":1,"slot":0}],"source":"F64"}],"output":[{"node":3,"field":0,"name":"bias"}],"taps":[{"name":"spread","from":{"node":2,"field":0}}]}} \ No newline at end of file diff --git a/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_2b_zero_bind.bp.json b/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_2b_zero_bind.bp.json new file mode 100644 index 0000000..ba4fc95 --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_2b_zero_bind.bp.json @@ -0,0 +1 @@ +{"format_version":1,"blueprint":{"name":"c319_zero","doc":"fast/slow SMA spread, tapped before the bias clamp","nodes":[{"primitive":{"type":"SMA","name":"fast","bound":[{"pos":0,"name":"length","kind":"I64","value":{"I64":0}}]}},{"primitive":{"type":"SMA","name":"slow","bound":[{"pos":0,"name":"length","kind":"I64","value":{"I64":8}}]}},{"primitive":{"type":"Sub","name":"sub"}},{"primitive":{"type":"Bias","name":"bias","bound":[{"pos":0,"name":"scale","kind":"F64","value":{"F64":0.5}}]}}],"edges":[{"from":0,"to":2,"slot":0,"from_field":0},{"from":1,"to":2,"slot":1,"from_field":0},{"from":2,"to":3,"slot":0,"from_field":0}],"input_roles":[{"name":"price","targets":[{"node":0,"slot":0},{"node":1,"slot":0}],"source":"F64"}],"output":[{"node":3,"field":0,"name":"bias"}],"taps":[{"name":"spread","from":{"node":2,"field":0}}]}} \ No newline at end of file diff --git a/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_3_campaign_sweep.json b/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_3_campaign_sweep.json new file mode 100644 index 0000000..15931da --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_3_campaign_sweep.json @@ -0,0 +1,22 @@ +{ + "format_version": 1, + "kind": "campaign", + "name": "c319-ger40-smacross-sweep", + "seed": 42, + "data": { + "instruments": ["GER40"], + "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] + }, + "strategies": [ + { + "ref": { "content_id": "7987bec19abfaccf8b98075511a05edcca5edce86755b781d3328cd75a7b4911" }, + "axes": { + "fast.length": { "kind": "I64", "values": [2, 4] }, + "slow.length": { "kind": "I64", "values": [16, 32] }, + "bias.scale": { "kind": "F64", "values": [0.5] } + } + } + ], + "process": { "ref": { "content_id": "954e735fc824ac74cceaaa6cbef8f8706a2fdaef3979ffb53cab854f0e3ca43b" } }, + "presentation": { "persist_taps": [], "emit": ["family_table", "selection_report"] } +} diff --git a/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_3_process_sweep.json b/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_3_process_sweep.json new file mode 100644 index 0000000..893e02d --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_3_process_sweep.json @@ -0,0 +1,9 @@ +{ + "format_version": 1, + "kind": "process", + "name": "c319-sweep-argmax", + "description": "Plain axis sweep, best member by SQN.", + "pipeline": [ + { "block": "std::sweep", "metric": "sqn", "select": "argmax" } + ] +} diff --git a/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_4_campaign_override.json b/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_4_campaign_override.json new file mode 100644 index 0000000..b008493 --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_4_campaign_override.json @@ -0,0 +1,21 @@ +{ + "format_version": 1, + "kind": "campaign", + "name": "c319-ger40-smacross-sweep-2axes", + "seed": 42, + "data": { + "instruments": ["GER40"], + "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] + }, + "strategies": [ + { + "ref": { "content_id": "7987bec19abfaccf8b98075511a05edcca5edce86755b781d3328cd75a7b4911" }, + "axes": { + "fast.length": { "kind": "I64", "values": [2, 4] }, + "slow.length": { "kind": "I64", "values": [16, 32] } + } + } + ], + "process": { "ref": { "content_id": "954e735fc824ac74cceaaa6cbef8f8706a2fdaef3979ffb53cab854f0e3ca43b" } }, + "presentation": { "persist_taps": [], "emit": ["family_table", "selection_report"] } +} diff --git a/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_4b_campaign_zerolen.json b/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_4b_campaign_zerolen.json new file mode 100644 index 0000000..5a13064 --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_4b_campaign_zerolen.json @@ -0,0 +1,21 @@ +{ + "format_version": 1, + "kind": "campaign", + "name": "c319-zero-length-axis", + "seed": 42, + "data": { + "instruments": ["GER40"], + "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] + }, + "strategies": [ + { + "ref": { "content_id": "7987bec19abfaccf8b98075511a05edcca5edce86755b781d3328cd75a7b4911" }, + "axes": { + "fast.length": { "kind": "I64", "values": [0] }, + "slow.length": { "kind": "I64", "values": [16, 32] } + } + } + ], + "process": { "ref": { "content_id": "954e735fc824ac74cceaaa6cbef8f8706a2fdaef3979ffb53cab854f0e3ca43b" } }, + "presentation": { "persist_taps": [], "emit": ["family_table", "selection_report"] } +} diff --git a/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_5_campaign_wf_flat.json b/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_5_campaign_wf_flat.json new file mode 100644 index 0000000..804eb8c --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_5_campaign_wf_flat.json @@ -0,0 +1,21 @@ +{ + "format_version": 1, + "kind": "campaign", + "name": "c319-ger40-flat-walkforward", + "seed": 42, + "data": { + "instruments": ["GER40"], + "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] + }, + "strategies": [ + { + "ref": { "content_id": "7987bec19abfaccf8b98075511a05edcca5edce86755b781d3328cd75a7b4911" }, + "axes": { + "fast.length": { "kind": "I64", "values": [4] }, + "slow.length": { "kind": "I64", "values": [4] } + } + } + ], + "process": { "ref": { "content_id": "a7220282128b56f53b75cf54c586a2ade11fd6a81d1638aeb3fb844fd0f51e3f" } }, + "presentation": { "persist_taps": [], "emit": ["family_table", "selection_report"] } +} diff --git a/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_5_process_wf.json b/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_5_process_wf.json new file mode 100644 index 0000000..92482c1 --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/c319_5_process_wf.json @@ -0,0 +1,10 @@ +{ + "format_version": 1, + "kind": "process", + "name": "c319-sweep-then-walkforward", + "description": "Sweep for a nominee, then walk it forward out of sample.", + "pipeline": [ + { "block": "std::sweep", "metric": "sqn", "select": "argmax" }, + { "block": "std::walk_forward", "in_sample_ms": 1209600000, "out_of_sample_ms": 604800000, "step_ms": 604800000, "mode": "rolling", "metric": "sqn", "select": "argmax" } + ] +} diff --git a/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/signal.json b/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/signal.json new file mode 100644 index 0000000..ca27c31 --- /dev/null +++ b/fieldtests/cycle-319-sugar-retirement/c319lab/blueprints/signal.json @@ -0,0 +1 @@ +{"format_version":1,"blueprint":{"name":"c319lab_signal","doc":"fast/slow SMA difference clamped into a directional bias","nodes":[{"primitive":{"type":"SMA","name":"fast","bound":[{"pos":0,"name":"length","kind":"I64","value":{"I64":2}}]}},{"primitive":{"type":"SMA","name":"slow","bound":[{"pos":0,"name":"length","kind":"I64","value":{"I64":4}}]}},{"primitive":{"type":"Sub"}},{"primitive":{"type":"Bias","name":"bias","bound":[{"pos":0,"name":"scale","kind":"F64","value":{"F64":0.5}}]}}],"edges":[{"from":0,"to":2,"slot":0,"from_field":0},{"from":1,"to":2,"slot":1,"from_field":0},{"from":2,"to":3,"slot":0,"from_field":0}],"input_roles":[{"name":"price","targets":[{"node":0,"slot":0},{"node":1,"slot":0}],"source":"F64"}],"output":[{"node":3,"field":0,"name":"bias"}]}} \ No newline at end of file