fieldtest: cycle-0107 campaign executor + on-ramp corpus (GREEN-core)

Verdict: the 0106 F7 wire is closed — campaign+process documents drive
aura campaign run through sweep -> gate -> walk_forward over the real
GER40 archive, realization recorded as a thin family-linking
CampaignRunRecord, bit-identical on re-run and across file/id
addressing (C1). 0106 F1/F5 on-ramp gaps confirmed repaired; the
honest-refusal surface (v1 boundary, empty gate exit 0 + truncation,
plateau/deflate composition, stale wf vocabulary, bad targets,
persist_taps loud deferral) exercised and clean. 0 bugs.

Findings triaged: F5 -> #202 (op-script vs envelope shape on the
on-ramp verbs), F6 -> #194 comment (content: prefix trap re-confirmed,
now spans graph register), F7 -> #203 (open-param coverage at validate;
raw-vs-wrapped path prose), F8 -> RED-first fix follows this commit
(SpanTooShort Debug leak), F9 -> #197 comment (rankable/per-member
roster split undiscoverable), F10 -> ratified store-before-gate on
#198 (derived: consistent with campaign register's intrinsic-only
gate; content-addressed store is an idempotent intent archive).
Orthogonal: #204 (aura new nested-.git gitlink hazard).

refs #198
This commit is contained in:
2026-07-03 22:29:14 +02:00
parent 428f83c542
commit 71405d4d86
44 changed files with 568 additions and 0 deletions
@@ -0,0 +1,215 @@
# Fieldtest — cycle 0107 — campaign executor + blueprint on-ramp — 2026-07-03
**Role:** downstream consumer (methodology / campaign designer), public interface
only (ledger C16/C18/C20/C24/C25, glossary, CLI `--help` + introspection verbs,
the 0106 fieldtest corpus as shape hints). No `crates/` source read. Binary
built from HEAD (`cargo build --workspace`, `target/debug/aura`, commit
`428f83c`). Real data: scaffolded `demo_project/` (`aura new`), `cargo build`
for the dylib, ran the executor over the local GER40 2024-09 Pepperstone
archive.
## Fixtures (this directory)
- `c0107_1_smacross.json` — SMA-cross op-script, lengths **bound** (content id `573262…`)
- `c0107_1_smacross_open.json` / `_open_built.json` — lengths **unbound** (sweepable), op-script + its `graph build` envelope (content id `597d71…`)
- `c0107_2_process.json` — sweep(sqn,argmax,deflate) → gate(expectancy_r>0) → walk_forward(rolling, ms lengths) (content id `5a88…`)
- `c0107_2_campaign.json` — campaign missing a `bias.scale` axis (validates, then fails run)
- `c0107_2_campaign_full.json` — the runnable campaign (all 3 open params covered), GER40, 2024-09
- `c0107_2_realization_campaign_runs.jsonl` — the recorded realization (3 identical runs + 1 gate-all)
- `c0107_3_process_{mc,gateall,badmetric}.json` + `c0107_3_campaign_*.json` — refusal probes
- `c0107_4_process_{plateau_wf,deflate_plateau,wf_toobig}.json` + `c0107_4_campaign_*.json` + `c0107_4_campaign_prefixref.json` — trip-up probes
- `demo_project/``aura new` scaffold + all docs (its `runs/` store is project-gitignored; the realization is copied out to the corpus root as evidence)
## Findings
### F1 [working] The full loop closes — 0106 F7 is answered
`aura campaign run c0107_2_campaign_full.json` (file = register-then-run) and
`aura campaign run 533aed18…` (id) both execute the cell
`GER40 × [2024-09-01,10-01]` through `std::sweep → std::gate →
std::walk_forward` over real data (exit 0). The gate `expectancy_r > 0` kept
survivors `[0,1,2]` (dropped the losing `fast=4/slow=16` member,
`expectancy_r=-0.022`); the sweep argmax winner was ordinal 0 (`sqn=1.054`);
walk-forward rolled 2 OOS folds re-sweeping **only** the survivor points and
stamped `manifest.selection` on the OOS winners. Emit honored: `family_table` +
`selection_report` lines, always the `campaign_run` record. The stored
`CampaignRunRecord` (`runs/campaign_runs.jsonl`) links
`{campaign, process, run, seed, cells[{stages: family_id / survivor_ordinals /
selection}]}` over untouched `families.jsonl` records, run-counted per campaign
id (3 successful runs → run 0/1/2). Intent → execution → recorded realization
is one continuous, reproducible path. → carry-on.
### F2 [working] Determinism is bit-identical across re-run and addressing mode
Two file runs and one id-addressed run of the same campaign are
**byte-identical** after normalizing only the per-campaign run counter in
family ids (`diff` clean on both pairs). Deflation nulls seed from the doc
`seed=42` (`overfit_probability`, `deflated_score` reproduce). Realization is a
pure function of doc + stores + data, as C1 promises. → carry-on.
### F3 [working] 0106 F1 closed — the document envelope is now introspectable
`aura campaign introspect --unwired <bare {}>` enumerates the whole envelope,
including the previously-invisible `seed`:
```
open slot: format_version (required, must be 1)
open slot: kind (required, must be "campaign")
open slot: name / data / strategies / process.ref / seed / presentation …
```
`process introspect --unwired {}` likewise names
`format_version/kind/name/pipeline`. The field names (`data`, `strategies`,
`process.ref`, `presentation`) that 0106 F1 could not map are now spelled out.
→ carry-on.
### F4 [working] The honest-refusal surface is loud, precise, and correctly disposed
All probed refusals were clean, actionable prose with the right exit code:
- v1 boundary: `process stage 1 (std::monte_carlo) is not executable in v1;
executable pipeline shape: std::sweep [std::gate]* [std::walk_forward]`
(exit 1). `std::generalize` is symmetric.
- gate-everything-out (`expectancy_r > 100`): exit **0**, `family_table` +
sweep `selection_report` still emitted, walk-forward **truncated**, loud
stderr `cell …: gate at stage 1 left no survivors; cell realization
truncated`.
- `plateau:mean` inside walk_forward: `walk_forward cannot use a plateau select
(a gated survivor subset has no parameter lattice)` (exit 1).
- `deflate:true` + non-argmax: `sweep deflate: true composes only with select
"argmax"` (exit 1).
- old 0106 wf vocab (`folds`): `block std::walk_forward: unknown slot "folds"`
(exit 1) — the 0107 machinery-true vocabulary correction is enforced.
- bogus file / unknown 64-hex id / uppercase-hex / outside-project: each exit 1
with a precise message (`neither a readable .json file nor a 64-hex content
id` / `no campaign <id> in the project store` / `campaign run needs a
project: … no Aura.toml found up from <cwd>`).
- `persist_taps` deferred **LOUDLY** on stderr before execution
(`persist_taps not yet honored (N tap(s) ignored)`), the 0106 F7 lesson
honored.
→ carry-on.
### F5 [friction] The on-ramp rejects the op-script; the `graph build` bridge is undocumented
The corpus's canonical strategy form is an **op-script** (`c0106_2_strategy.json`,
`c0107_1_*`). `aura graph introspect --content-id FILE` accepts it
(shape-discriminated) — but `aura graph register FILE` and `aura graph
introspect --params FILE` **reject** it with a raw serde message:
```
aura: blueprint document is not valid JSON: invalid type: map, expected u32 at line 2 column 2
```
Only the envelope emitted by `aura graph build < op-script > envelope.json` is
accepted. Nothing in `--help`, the glossary `blueprint` entry, or the error
names this `graph build` step, and the three on-ramp verbs disagree on which
shapes they accept. (Once bridged, the content id is shape-invariant —
op-script and envelope both hash to `573262…`, so `register` and a ref computed
from the op-script agree; this part is correct.)
Repro: `aura graph register c0107_1_smacross_open.json`.
→ plan: shape-discriminate the op-list in `register`/`--params` (as
`--content-id` already does), or make the error name the `graph build` bridge.
### F6 [friction] The `content:` prefix trap persists and the on-ramp emits the wrong-to-paste form
`graph|process|campaign register` and `introspect --content-id` all print
`content:<hash>`, but every `ref` wants the **bare** hash. A campaign whose
`process.ref` carries the copied `content:5a88…` form **passes intrinsic
validation** and then fails referential:
```
aura: campaign references do not resolve:
process content:5a88…6ea not found in the project store
```
The error now echoes the offending prefixed ref (an improvement over 0106 F3)
but never says "strip the `content:` prefix", and `register` still prints
exactly the form that breaks. This directly taxes the on-ramp the cycle set out
to smooth.
Repro: `aura campaign validate c0107_4_campaign_prefixref.json`.
→ plan: one bare display form across verbs, or accept/strip the `content:`
prefix in refs (carried from 0106 F3, still open: #194).
### F7 [friction] `campaign validate` passes but `campaign run` aborts when an open param is uncovered
Referential validation reports `all references resolve, axes are in the param
space` (exit 0), but it only checks that each axis **name** is in `param_space`
— not that **every** open param is covered by an axis. The open blueprint has
three open params (`fast.length`, `slow.length`, `bias.scale`); a campaign
sweeping only the two lengths **validates**, then aborts at member-bind:
```
aura: a member failed to bind: open param "graph.bias.scale" of strategy 597d71… is bound by no campaign axis
```
The executor's "every open knob required, no default" rule (documented for
`sweep`/`walkforward` in the glossary) is not mirrored in the validator, so
"valid" ≠ "runnable". (Secondary: the bind error uses the wrapped
`graph.bias.scale` path while `--params` and the axis use the raw `bias.scale`
— two namespaces for one knob.)
Repro: `aura campaign validate c0107_2_campaign.json` (passes) then
`aura campaign run c0107_2_campaign.json` (aborts).
→ plan: extend the referential tier to require full open-param coverage,
surfacing the missing knob at validate time; reconcile the raw-vs-wrapped param
path in the bind message.
### F8 [friction] The walk-forward window-fit refusal leaks a raw Rust `Debug` struct
A walk_forward whose `in_sample_ms` exceeds the campaign window refuses
correctly, but in internal `{:?}` form, unlike its clean sibling refusals:
```
aura: process stage 1: walk_forward windows do not fit the campaign window:
SpanTooShort { span: (Timestamp(1725148800000), Timestamp(1727740800000)), need: 315964799999 }
```
The `SpanTooShort {…}` struct, the `Timestamp()` wrapper, and the
unit-unlabeled `need` (ms) break the "Debug-free house seam" the cycle
otherwise maintains, and a user cannot easily see that `need` is
`in_sample_ms + out_of_sample_ms` in ms against the window span.
Repro: `aura campaign run c0107_4_campaign_wf_toobig.json`.
→ debug (RED-pin the prose form).
### F9 [doc-gap] The rankable / gate metric roster is enumerable by no verb, nor by the refusal
Block hints say `metric name (see metric_vocabulary)`, but no verb lists it
(`--vocabulary` is the block list; `--block metric_vocabulary` → `unknown
block`). `process validate` accepts **any** string (`profit_factor` passes
intrinsic), and the run-time refusal names no roster:
```
aura: process stage 0: metric "profit_factor" is not rankable (winner selection needs one of the registry's rankable metrics)
```
`profit_factor` is itself emitted in every member's metrics block, so the
exists-but-not-rankable split is invisible. A campaign author must guess the
sweep/gate/wf metric names (0106 F6, still open: #197).
→ tighten docs: expose the rankable + gate metric rosters via `process
introspect` (or enumerate them in the refusal).
### F10 [spec_gap] Register-then-run stores the campaign before the gate — unrunnable docs accumulate
Every `campaign run <file>` issued left a `runs/campaigns/<id>.json` (9
stored), including campaigns that then failed the referential gate
(`prefixref`) or preflight (`mc`/`badmetric`/`plateauwf`/`deflateplateau`/
`wf_toobig`). The store thus accumulates never-runnable and
referentially-broken documents, with no cleanup. The ledger is silent on
whether the file sugar should gate before storing, and whether the
content-addressed store should hold referentially-broken docs.
→ ratify (accept intrinsic-keyed store as-is) or tighten (gate before storing).
## Verdict
**Yes — the campaign+process pair now delivers the full loop the 0106 verdict
said was one wire short.** F7 (0106) is closed end to end: a campaign document
+ its referenced process document drive `aura campaign run` through
`sweep → gate → walk_forward` over the real GER40 archive, and the run's
realization is recorded as a thin, family-linking `CampaignRunRecord` that is
content-addressed, run-counted, and **bit-identical on re-run** — persisted
intent finally has a consumer, and every id, axis, gate, and selection earns
its reason to exist. The authoring on-ramp that 0106 flagged is substantially
repaired too: `graph register` + `introspect --params` (file and store-id) +
`--content-id` file mode give a blueprint ref a resolvable path (F5-0106), and
`--unwired {}` makes the whole envelope, `seed` included, derivable (F1-0106).
The honest-refusal surface is a genuine strength — v1 boundary, empty gate
(exit 0 + truncation), plateau/deflate composition, stale wf vocabulary, and
every bad target are refused loudly, precisely, and with the correct
disposition.
What remains is friction concentrated at the *first-author* edge, not the
loop: the on-ramp verbs disagree on op-script vs envelope shape and hide the
`graph build` bridge (F5); the `content:` prefix that every
`register`/`--content-id` prints is the exact form that silently breaks a ref
(F6); `campaign validate` blesses a campaign the executor then rejects for an
uncovered open param (F7); one preflight fault leaks a raw `Debug` struct
(F8); and the metric roster a process must name is still discoverable nowhere
(F9). None block the loop; all tax the newcomer. One spec silence to settle:
whether register-then-run should store before or after the gate (F10).
Counts: working 4 (F1F4), friction 4 (F5F8), doc-gap 1 (F9), spec-gap 1
(F10), bugs 0.
## Orthogonal concern (out of 0107 scope)
`aura new` (cycle 0103) scaffolds a **nested `.git` repo** inside the project
directory — a gitlink/submodule hazard when the scaffold is embedded in the
tracked `fieldtests/` corpus. `demo_project/.git` (and the large
`demo_project/target/`) were removed so the corpus commits cleanly. Worth a
scaffold-side note (`--no-git` or skip when nested under a repo).
@@ -0,0 +1,12 @@
[
{"op": "source", "role": "price", "kind": "F64"},
{"op": "add", "type": "SMA", "name": "fast", "bind": {"length": {"I64": 8}}},
{"op": "add", "type": "SMA", "name": "slow", "bind": {"length": {"I64": 16}}},
{"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"},
{"op": "connect", "from": "sub.value", "to": "bias.signal"},
{"op": "expose", "from": "bias.bias", "as": "bias"}
]
@@ -0,0 +1,12 @@
[
{"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"},
{"op": "connect", "from": "sub.value", "to": "bias.signal"},
{"op": "expose", "from": "bias.bias", "as": "bias"}
]
@@ -0,0 +1 @@
{"format_version":1,"blueprint":{"name":"graph","nodes":[{"primitive":{"type":"SMA","name":"fast"}},{"primitive":{"type":"SMA","name":"slow"}},{"primitive":{"type":"Sub","name":"sub"}},{"primitive":{"type":"Bias","name":"bias"}}],"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"}]}}
@@ -0,0 +1,18 @@
{
"format_version": 1,
"kind": "campaign",
"name": "ger40-smacross-wf",
"seed": 42,
"data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] },
"strategies": [
{
"ref": { "content_id": "597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a" },
"axes": {
"fast.length": { "kind": "I64", "values": [2, 4] },
"slow.length": { "kind": "I64", "values": [8, 16] }
}
}
],
"process": { "ref": { "content_id": "5a88cec04917fdcb328a1de6a8eccac8dcb56655631771eff2151a8d551708ea" } },
"presentation": { "persist_taps": ["bias", "equity"], "emit": ["family_table", "selection_report"] }
}
@@ -0,0 +1,19 @@
{
"format_version": 1,
"kind": "campaign",
"name": "ger40-smacross-wf",
"seed": 42,
"data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] },
"strategies": [
{
"ref": { "content_id": "597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a" },
"axes": {
"fast.length": { "kind": "I64", "values": [2, 4] },
"slow.length": { "kind": "I64", "values": [8, 16] },
"bias.scale": { "kind": "F64", "values": [0.5] }
}
}
],
"process": { "ref": { "content_id": "5a88cec04917fdcb328a1de6a8eccac8dcb56655631771eff2151a8d551708ea" } },
"presentation": { "persist_taps": ["bias", "equity"], "emit": ["family_table", "selection_report"] }
}
@@ -0,0 +1,11 @@
{
"format_version": 1,
"kind": "process",
"name": "robust-sweep-wf-v1",
"description": "Sweep with deflation, gate on positive expectancy, then rolling walk-forward confirm.",
"pipeline": [
{ "block": "std::sweep", "metric": "sqn", "select": "argmax", "deflate": true },
{ "block": "std::gate", "all": [ { "metric": "expectancy_r", "cmp": "gt", "value": 0.0 } ] },
{ "block": "std::walk_forward", "in_sample_ms": 1209600000, "out_of_sample_ms": 604800000, "step_ms": 604800000, "mode": "rolling", "metric": "sqn", "select": "argmax" }
]
}
@@ -0,0 +1,4 @@
{"campaign":"533aed18e20983ba40cae49de74ab2d1506ecefbcdd5872af6f860b6a1c22345","process":"5a88cec04917fdcb328a1de6a8eccac8dcb56655631771eff2151a8d551708ea","run":0,"seed":42,"cells":[{"strategy":"597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a","instrument":"GER40","window_ms":[1725148800000,1727740800000],"stages":[{"block":"std::sweep","family_id":"533aed18-0-GER40-w0-s0-0","selection":{"winner_ordinal":0,"params":[["bias.scale",{"F64":0.5}],["fast.length",{"I64":2}],["slow.length",{"I64":8}]],"selection":{"selection_metric":"sqn","n_trials":4,"raw_winner_metric":1.0540214890316064,"mode":"Argmax","deflated_score":-1.0290009962190139,"overfit_probability":0.3876123876123876,"n_resamples":1000,"block_len":5,"seed":42}}},{"block":"std::gate","survivor_ordinals":[0,1,2]},{"block":"std::walk_forward","family_id":"533aed18-0-GER40-w0-s2-0"}]}]}
{"campaign":"533aed18e20983ba40cae49de74ab2d1506ecefbcdd5872af6f860b6a1c22345","process":"5a88cec04917fdcb328a1de6a8eccac8dcb56655631771eff2151a8d551708ea","run":1,"seed":42,"cells":[{"strategy":"597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a","instrument":"GER40","window_ms":[1725148800000,1727740800000],"stages":[{"block":"std::sweep","family_id":"533aed18-0-GER40-w0-s0-1","selection":{"winner_ordinal":0,"params":[["bias.scale",{"F64":0.5}],["fast.length",{"I64":2}],["slow.length",{"I64":8}]],"selection":{"selection_metric":"sqn","n_trials":4,"raw_winner_metric":1.0540214890316064,"mode":"Argmax","deflated_score":-1.0290009962190139,"overfit_probability":0.3876123876123876,"n_resamples":1000,"block_len":5,"seed":42}}},{"block":"std::gate","survivor_ordinals":[0,1,2]},{"block":"std::walk_forward","family_id":"533aed18-0-GER40-w0-s2-1"}]}]}
{"campaign":"533aed18e20983ba40cae49de74ab2d1506ecefbcdd5872af6f860b6a1c22345","process":"5a88cec04917fdcb328a1de6a8eccac8dcb56655631771eff2151a8d551708ea","run":2,"seed":42,"cells":[{"strategy":"597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a","instrument":"GER40","window_ms":[1725148800000,1727740800000],"stages":[{"block":"std::sweep","family_id":"533aed18-0-GER40-w0-s0-2","selection":{"winner_ordinal":0,"params":[["bias.scale",{"F64":0.5}],["fast.length",{"I64":2}],["slow.length",{"I64":8}]],"selection":{"selection_metric":"sqn","n_trials":4,"raw_winner_metric":1.0540214890316064,"mode":"Argmax","deflated_score":-1.0290009962190139,"overfit_probability":0.3876123876123876,"n_resamples":1000,"block_len":5,"seed":42}}},{"block":"std::gate","survivor_ordinals":[0,1,2]},{"block":"std::walk_forward","family_id":"533aed18-0-GER40-w0-s2-2"}]}]}
{"campaign":"d849dc2f3278782729a0c07094a3862514063463cc3d9245688245e146e041c8","process":"944cc95f14e6908c702a70eea4ea4190dcb5ee7c06d91be85a223c045c786e4c","run":0,"seed":42,"cells":[{"strategy":"597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a","instrument":"GER40","window_ms":[1725148800000,1727740800000],"stages":[{"block":"std::sweep","family_id":"d849dc2f-0-GER40-w0-s0-0","selection":{"winner_ordinal":0,"params":[["bias.scale",{"F64":0.5}],["fast.length",{"I64":2}],["slow.length",{"I64":8}]],"selection":{"selection_metric":"sqn","n_trials":4,"raw_winner_metric":1.0540214890316064,"mode":"Argmax"}}},{"block":"std::gate","survivor_ordinals":[]}]}]}
@@ -0,0 +1,8 @@
{
"format_version": 1, "kind": "campaign", "name": "camp-badmetric", "seed": 42,
"data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] },
"strategies": [ { "ref": { "content_id": "597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a" },
"axes": { "fast.length": { "kind": "I64", "values": [2, 4] }, "slow.length": { "kind": "I64", "values": [8, 16] }, "bias.scale": { "kind": "F64", "values": [0.5] } } } ],
"process": { "ref": { "content_id": "363feac72afb69fd2384ce851a339856fd6d1981d4b353777a75cacf89783fd8" } },
"presentation": { "persist_taps": [], "emit": ["family_table", "selection_report"] }
}
@@ -0,0 +1,8 @@
{
"format_version": 1, "kind": "campaign", "name": "camp-gateall", "seed": 42,
"data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] },
"strategies": [ { "ref": { "content_id": "597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a" },
"axes": { "fast.length": { "kind": "I64", "values": [2, 4] }, "slow.length": { "kind": "I64", "values": [8, 16] }, "bias.scale": { "kind": "F64", "values": [0.5] } } } ],
"process": { "ref": { "content_id": "944cc95f14e6908c702a70eea4ea4190dcb5ee7c06d91be85a223c045c786e4c" } },
"presentation": { "persist_taps": [], "emit": ["family_table", "selection_report"] }
}
@@ -0,0 +1,8 @@
{
"format_version": 1, "kind": "campaign", "name": "camp-mc", "seed": 42,
"data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] },
"strategies": [ { "ref": { "content_id": "597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a" },
"axes": { "fast.length": { "kind": "I64", "values": [2, 4] }, "slow.length": { "kind": "I64", "values": [8, 16] }, "bias.scale": { "kind": "F64", "values": [0.5] } } } ],
"process": { "ref": { "content_id": "47af2e65dc2388b644e8fc8fbb872fca52e70bdf5090b4b3dac818dc9d1dfdce" } },
"presentation": { "persist_taps": [], "emit": ["family_table", "selection_report"] }
}
@@ -0,0 +1,2 @@
{ "format_version": 1, "kind": "process", "name": "sweep-badmetric",
"pipeline": [ { "block": "std::sweep", "metric": "profit_factor", "select": "argmax" } ] }
@@ -0,0 +1,6 @@
{ "format_version": 1, "kind": "process", "name": "sweep-gateall-wf",
"pipeline": [
{ "block": "std::sweep", "metric": "sqn", "select": "argmax" },
{ "block": "std::gate", "all": [ { "metric": "expectancy_r", "cmp": "gt", "value": 100.0 } ] },
{ "block": "std::walk_forward", "in_sample_ms": 1209600000, "out_of_sample_ms": 604800000, "step_ms": 604800000, "mode": "rolling", "metric": "sqn", "select": "argmax" }
] }
@@ -0,0 +1,5 @@
{ "format_version": 1, "kind": "process", "name": "sweep-then-mc",
"pipeline": [
{ "block": "std::sweep", "metric": "sqn", "select": "argmax" },
{ "block": "std::monte_carlo", "resamples": 1000, "block_len": 5 }
] }
@@ -0,0 +1,5 @@
{ "format_version": 1, "kind": "campaign", "name": "camp-deflate-plateau", "seed": 42,
"data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] },
"strategies": [ { "ref": { "content_id": "597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a" }, "axes": { "fast.length": { "kind": "I64", "values": [2,4] }, "slow.length": { "kind": "I64", "values": [8,16] }, "bias.scale": { "kind": "F64", "values": [0.5] } } } ],
"process": { "ref": { "content_id": "c588f8ad06028a447768b8566737a0c51f0df855350a131a6d08c50ae3f0df0f" } },
"presentation": { "persist_taps": [], "emit": ["family_table"] } }
@@ -0,0 +1,5 @@
{ "format_version": 1, "kind": "campaign", "name": "camp-plateau-wf", "seed": 42,
"data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] },
"strategies": [ { "ref": { "content_id": "597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a" }, "axes": { "fast.length": { "kind": "I64", "values": [2,4] }, "slow.length": { "kind": "I64", "values": [8,16] }, "bias.scale": { "kind": "F64", "values": [0.5] } } } ],
"process": { "ref": { "content_id": "34d67ae1bdc029157fe36a68d6298e7869483a8a1d05c566fcf9e901dadc84d4" } },
"presentation": { "persist_taps": [], "emit": ["family_table"] } }
@@ -0,0 +1,5 @@
{ "format_version": 1, "kind": "campaign", "name": "prefix-trap", "seed": 42,
"data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] },
"strategies": [ { "ref": { "content_id": "597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a" }, "axes": { "fast.length": { "kind": "I64", "values": [2,4] }, "slow.length": { "kind": "I64", "values": [8,16] }, "bias.scale": { "kind": "F64", "values": [0.5] } } } ],
"process": { "ref": { "content_id": "content:5a88cec04917fdcb328a1de6a8eccac8dcb56655631771eff2151a8d551708ea" } },
"presentation": { "persist_taps": [], "emit": ["family_table"] } }
@@ -0,0 +1,5 @@
{ "format_version": 1, "kind": "campaign", "name": "wf-toobig", "seed": 42,
"data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] },
"strategies": [ { "ref": { "content_id": "597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a" }, "axes": { "fast.length": { "kind": "I64", "values": [2,4] }, "slow.length": { "kind": "I64", "values": [8,16] }, "bias.scale": { "kind": "F64", "values": [0.5] } } } ],
"process": { "ref": { "content_id": "6e17d18baa2cfc27826bab5e0304d0d6e6e082921fcaad7fd585d858485db9cc" } },
"presentation": { "persist_taps": [], "emit": ["family_table"] } }
@@ -0,0 +1,2 @@
{ "format_version": 1, "kind": "process", "name": "deflate-plateau",
"pipeline": [ { "block": "std::sweep", "metric": "sqn", "select": "plateau:worst", "deflate": true } ] }
@@ -0,0 +1,3 @@
{ "format_version": 1, "kind": "process", "name": "plateau-in-wf",
"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": "plateau:mean" } ] }
@@ -0,0 +1,3 @@
{ "format_version": 1, "kind": "process", "name": "wf-toobig",
"pipeline": [ { "block": "std::sweep", "metric": "sqn", "select": "argmax" },
{ "block": "std::walk_forward", "in_sample_ms": 315360000000, "out_of_sample_ms": 604800000, "step_ms": 604800000, "mode": "rolling", "metric": "sqn", "select": "argmax" } ] }
@@ -0,0 +1 @@
{ "format_version": 1, "kind": "process", "name": "bad", "pipeline": [ { "block": "std::sweep", "metric": "profit_factor", "select": "argmax" } ] }
@@ -0,0 +1,3 @@
/target
Cargo.lock
/runs
@@ -0,0 +1,3 @@
# Static project context only (C17); paths only.
[paths]
runs = "runs"
@@ -0,0 +1,10 @@
# demo_project — an aura research project
This crate is an aura project: a cdylib of node/strategy blueprints the
`aura` host loads during research (see the engine's docs/project-layout.md).
- Build: `cargo build` (the next `aura` invocation loads the fresh dylib)
- Run: `aura run blueprints/signal.json` (from anywhere inside this dir)
- Nodes live in `src/`; each is registered in `vocabulary()`/`type_ids()`
under the `demo_project::` namespace prefix.
- Topology is data (`blueprints/*.json`), node logic is Rust.
@@ -0,0 +1,14 @@
[package]
name = "demo_project"
version = "0.1.0"
edition = "2024"
publish = false
[lib]
crate-type = ["cdylib"]
[dependencies]
aura-core = { path = "/home/brummel/dev/aura/crates/aura-core" }
# Standalone workspace root: never a member of an enclosing workspace.
[workspace]
@@ -0,0 +1 @@
{"format_version":1,"blueprint":{"name":"demo_project_signal","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}}]}},{"primitive":{"type":"demo_project::Identity"}}],"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},{"from":3,"to":4,"slot":0,"from_field":0}],"input_roles":[{"name":"price","targets":[{"node":0,"slot":0},{"node":1,"slot":0}],"source":"F64"}],"output":[{"node":4,"field":0,"name":"bias"}]}}
@@ -0,0 +1,18 @@
{
"format_version": 1,
"kind": "campaign",
"name": "ger40-smacross-wf",
"seed": 42,
"data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] },
"strategies": [
{
"ref": { "content_id": "597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a" },
"axes": {
"fast.length": { "kind": "I64", "values": [2, 4] },
"slow.length": { "kind": "I64", "values": [8, 16] }
}
}
],
"process": { "ref": { "content_id": "5a88cec04917fdcb328a1de6a8eccac8dcb56655631771eff2151a8d551708ea" } },
"presentation": { "persist_taps": ["bias", "equity"], "emit": ["family_table", "selection_report"] }
}
@@ -0,0 +1,19 @@
{
"format_version": 1,
"kind": "campaign",
"name": "ger40-smacross-wf",
"seed": 42,
"data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] },
"strategies": [
{
"ref": { "content_id": "597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a" },
"axes": {
"fast.length": { "kind": "I64", "values": [2, 4] },
"slow.length": { "kind": "I64", "values": [8, 16] },
"bias.scale": { "kind": "F64", "values": [0.5] }
}
}
],
"process": { "ref": { "content_id": "5a88cec04917fdcb328a1de6a8eccac8dcb56655631771eff2151a8d551708ea" } },
"presentation": { "persist_taps": ["bias", "equity"], "emit": ["family_table", "selection_report"] }
}
@@ -0,0 +1,8 @@
{
"format_version": 1, "kind": "campaign", "name": "camp-badmetric", "seed": 42,
"data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] },
"strategies": [ { "ref": { "content_id": "597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a" },
"axes": { "fast.length": { "kind": "I64", "values": [2, 4] }, "slow.length": { "kind": "I64", "values": [8, 16] }, "bias.scale": { "kind": "F64", "values": [0.5] } } } ],
"process": { "ref": { "content_id": "363feac72afb69fd2384ce851a339856fd6d1981d4b353777a75cacf89783fd8" } },
"presentation": { "persist_taps": [], "emit": ["family_table", "selection_report"] }
}
@@ -0,0 +1,8 @@
{
"format_version": 1, "kind": "campaign", "name": "camp-gateall", "seed": 42,
"data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] },
"strategies": [ { "ref": { "content_id": "597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a" },
"axes": { "fast.length": { "kind": "I64", "values": [2, 4] }, "slow.length": { "kind": "I64", "values": [8, 16] }, "bias.scale": { "kind": "F64", "values": [0.5] } } } ],
"process": { "ref": { "content_id": "944cc95f14e6908c702a70eea4ea4190dcb5ee7c06d91be85a223c045c786e4c" } },
"presentation": { "persist_taps": [], "emit": ["family_table", "selection_report"] }
}
@@ -0,0 +1,8 @@
{
"format_version": 1, "kind": "campaign", "name": "camp-mc", "seed": 42,
"data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] },
"strategies": [ { "ref": { "content_id": "597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a" },
"axes": { "fast.length": { "kind": "I64", "values": [2, 4] }, "slow.length": { "kind": "I64", "values": [8, 16] }, "bias.scale": { "kind": "F64", "values": [0.5] } } } ],
"process": { "ref": { "content_id": "47af2e65dc2388b644e8fc8fbb872fca52e70bdf5090b4b3dac818dc9d1dfdce" } },
"presentation": { "persist_taps": [], "emit": ["family_table", "selection_report"] }
}
@@ -0,0 +1,2 @@
{ "format_version": 1, "kind": "process", "name": "sweep-badmetric",
"pipeline": [ { "block": "std::sweep", "metric": "profit_factor", "select": "argmax" } ] }
@@ -0,0 +1,6 @@
{ "format_version": 1, "kind": "process", "name": "sweep-gateall-wf",
"pipeline": [
{ "block": "std::sweep", "metric": "sqn", "select": "argmax" },
{ "block": "std::gate", "all": [ { "metric": "expectancy_r", "cmp": "gt", "value": 100.0 } ] },
{ "block": "std::walk_forward", "in_sample_ms": 1209600000, "out_of_sample_ms": 604800000, "step_ms": 604800000, "mode": "rolling", "metric": "sqn", "select": "argmax" }
] }
@@ -0,0 +1,5 @@
{ "format_version": 1, "kind": "process", "name": "sweep-then-mc",
"pipeline": [
{ "block": "std::sweep", "metric": "sqn", "select": "argmax" },
{ "block": "std::monte_carlo", "resamples": 1000, "block_len": 5 }
] }
@@ -0,0 +1,5 @@
{ "format_version": 1, "kind": "campaign", "name": "camp-deflate-plateau", "seed": 42,
"data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] },
"strategies": [ { "ref": { "content_id": "597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a" }, "axes": { "fast.length": { "kind": "I64", "values": [2,4] }, "slow.length": { "kind": "I64", "values": [8,16] }, "bias.scale": { "kind": "F64", "values": [0.5] } } } ],
"process": { "ref": { "content_id": "c588f8ad06028a447768b8566737a0c51f0df855350a131a6d08c50ae3f0df0f" } },
"presentation": { "persist_taps": [], "emit": ["family_table"] } }
@@ -0,0 +1,5 @@
{ "format_version": 1, "kind": "campaign", "name": "camp-plateau-wf", "seed": 42,
"data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] },
"strategies": [ { "ref": { "content_id": "597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a" }, "axes": { "fast.length": { "kind": "I64", "values": [2,4] }, "slow.length": { "kind": "I64", "values": [8,16] }, "bias.scale": { "kind": "F64", "values": [0.5] } } } ],
"process": { "ref": { "content_id": "34d67ae1bdc029157fe36a68d6298e7869483a8a1d05c566fcf9e901dadc84d4" } },
"presentation": { "persist_taps": [], "emit": ["family_table"] } }
@@ -0,0 +1,5 @@
{ "format_version": 1, "kind": "campaign", "name": "prefix-trap", "seed": 42,
"data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] },
"strategies": [ { "ref": { "content_id": "597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a" }, "axes": { "fast.length": { "kind": "I64", "values": [2,4] }, "slow.length": { "kind": "I64", "values": [8,16] }, "bias.scale": { "kind": "F64", "values": [0.5] } } } ],
"process": { "ref": { "content_id": "content:5a88cec04917fdcb328a1de6a8eccac8dcb56655631771eff2151a8d551708ea" } },
"presentation": { "persist_taps": [], "emit": ["family_table"] } }
@@ -0,0 +1,5 @@
{ "format_version": 1, "kind": "campaign", "name": "wf-toobig", "seed": 42,
"data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] },
"strategies": [ { "ref": { "content_id": "597d719b7ac607158cda3e68cd497387620397a5e93087e23da512876dafba9a" }, "axes": { "fast.length": { "kind": "I64", "values": [2,4] }, "slow.length": { "kind": "I64", "values": [8,16] }, "bias.scale": { "kind": "F64", "values": [0.5] } } } ],
"process": { "ref": { "content_id": "6e17d18baa2cfc27826bab5e0304d0d6e6e082921fcaad7fd585d858485db9cc" } },
"presentation": { "persist_taps": [], "emit": ["family_table"] } }
@@ -0,0 +1,2 @@
{ "format_version": 1, "kind": "process", "name": "deflate-plateau",
"pipeline": [ { "block": "std::sweep", "metric": "sqn", "select": "plateau:worst", "deflate": true } ] }
@@ -0,0 +1,3 @@
{ "format_version": 1, "kind": "process", "name": "plateau-in-wf",
"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": "plateau:mean" } ] }
@@ -0,0 +1,3 @@
{ "format_version": 1, "kind": "process", "name": "wf-toobig",
"pipeline": [ { "block": "std::sweep", "metric": "sqn", "select": "argmax" },
{ "block": "std::walk_forward", "in_sample_ms": 315360000000, "out_of_sample_ms": 604800000, "step_ms": 604800000, "mode": "rolling", "metric": "sqn", "select": "argmax" } ] }
@@ -0,0 +1,76 @@
//! demo_project — an aura research project: node logic + the exported vocabulary.
//!
//! Every node type this crate provides is registered in `vocabulary()` /
//! `type_ids()` under the `demo_project::` namespace prefix; the `aura` host loads
//! this cdylib per invocation and merges it with the std vocabulary.
use aura_core::{
Cell, Ctx, FieldSpec, Firing, Node, NodeSchema, PortSpec, PrimitiveBuilder,
ScalarKind,
};
/// One-input f64 pass-through. Emits `None` until its input has a value.
pub struct Identity {
out: [Cell; 1],
}
impl Identity {
pub fn new() -> Self {
Self { out: [Cell::from_f64(0.0)] }
}
pub fn builder() -> PrimitiveBuilder {
PrimitiveBuilder::new(
"demo_project::Identity",
NodeSchema {
inputs: vec![PortSpec {
kind: ScalarKind::F64,
firing: Firing::Any,
name: "value".into(),
}],
output: vec![FieldSpec { name: "value".into(), kind: ScalarKind::F64 }],
params: vec![],
},
|_| Box::new(Identity::new()),
)
}
}
impl Default for Identity {
fn default() -> Self {
Self::new()
}
}
impl Node for Identity {
fn lookbacks(&self) -> Vec<usize> {
vec![1]
}
fn eval(&mut self, ctx: Ctx<'_>) -> Option<&[Cell]> {
let w = ctx.f64_in(0);
if w.is_empty() {
return None;
}
self.out[0] = Cell::from_f64(w[0]);
Some(&self.out)
}
fn label(&self) -> String {
"demo_project::Identity".to_string()
}
}
fn vocabulary(type_id: &str) -> Option<PrimitiveBuilder> {
match type_id {
"demo_project::Identity" => Some(Identity::builder()),
_ => None,
}
}
fn type_ids() -> &'static [&'static str] {
&["demo_project::Identity"]
}
aura_core::aura_project! {
namespace: "demo_project",
vocabulary: vocabulary,
type_ids: type_ids,
}
@@ -0,0 +1 @@
{"format_version":1,"blueprint":{"name":"graph","nodes":[{"primitive":{"type":"SMA","name":"fast","bound":[{"pos":0,"name":"length","kind":"I64","value":{"I64":8}}]}},{"primitive":{"type":"SMA","name":"slow","bound":[{"pos":0,"name":"length","kind":"I64","value":{"I64":16}}]}},{"primitive":{"type":"Sub","name":"sub"}},{"primitive":{"type":"Bias","name":"bias"}}],"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"}]}}