diff --git a/fieldtests/milestone-project-environment/FINDINGS.md b/fieldtests/milestone-project-environment/FINDINGS.md new file mode 100644 index 0000000..34eb1a1 --- /dev/null +++ b/fieldtests/milestone-project-environment/FINDINGS.md @@ -0,0 +1,191 @@ +# Fieldtest — milestone "Project environment — the project-as-crate authoring loop" (#180) — 2026-07-02 + +**Status:** Draft — awaiting orchestrator triage +**Author:** fieldtester (dispatched as the milestone-close gate) + +## Scope + +The milestone-close gate for the **project-as-crate authoring loop**: `aura new` +scaffolds a buildable cdylib project; inside it the `aura` host discovers +`Aura.toml`, cargo-builds + loads the project cdylib, merges the project +vocabulary with `aura-std`, and runs blueprints with project provenance in the +manifest; `aura graph introspect --vocabulary | --content-id | --identity-id` +introspects the merged surface and topology ids. + +Run entirely from the **public interface** — `README.md`, +`docs/project-layout.md`, `docs/glossary.md`, `docs/design/INDEX.md` +(C13/C16/C17/C24), `aura … --help`, and the fieldtests corpus *shape*. No +`crates/*/src` and no `crates/*/tests` were read; no rustdoc was consulted. The +only node-authoring template available was the scaffolded `Identity` node. +Artefact under test: `target/debug/aura`, rebuilt from HEAD via +`cargo build -p aura-cli` before the run; the project cdylib rebuilt with +`cargo build` in the project between edits. + +## Tasks + +All fixtures under `fieldtests/milestone-project-environment/`. The scaffolded +project is `momentum-lab/`. + +### Task 1 — scaffold -> build -> run -> run-again -> provenance — WORKS +Commands (verbatim): + + aura new momentum-lab # -> "created project `momentum-lab` (namespace `momentum_lab`)" + cd momentum-lab && cargo build # clean + aura run blueprints/signal.json # -> s1_starter_run.json + aura run blueprints/signal.json (x2, diff) # byte-IDENTICAL (determinism) + +- The emitted crate is buildable as-is: `crate-type=["cdylib"]`, an empty + `[workspace]` table (so it builds under the engine tree), path-dep on + `aura-core`, a `CLAUDE.md`, `.gitignore`, an `Aura.toml` (`[paths] runs`), a + `src/lib.rs` with a worked `Identity` node registered via `aura_project!`, and + a starter `blueprints/signal.json` that already wires the project's own + `momentum_lab::Identity` node at the graph tail — so the very first run + exercises the merged vocabulary, not just std. +- The run report's manifest carries the milestone's headline provenance: + `"project":{"namespace":"momentum_lab","dylib_sha256":"ceda123f…"}`. Two runs + are byte-identical (C1). Evidence: `s1_starter_run.json`. + +### Task 2 — author your own node (the real authoring loop) — WORKS +Edited `momentum-lab/src/lib.rs` to add a `Negate` (f64 sign-flip) node +following the scaffolded `Identity` template, registered it in +`vocabulary()`/`type_ids()`, then: + + cargo build # clean + aura graph introspect --vocabulary # now lists momentum_lab::Negate + aura graph build < s2_negate.ops.json > s2_negate.bp.json # resolves the project node + aura run s2_negate.bp.json # -> s2_negate_run.json + +- The op-list (`s2_negate.ops.json`, canonical authoring form per README) wires + `price -> SMA/SMA -> Sub -> Bias -> momentum_lab::Negate`. `graph build` + resolved the project node and emitted a runnable blueprint (`s2_negate.bp.json`). +- The new node visibly changed behaviour: `total_pips` went `+0.34185 -> -0.34185` + (exact sign flip), the R block changed accordingly, and the manifest's + `dylib_sha256` updated (`ceda123f… -> 70263c83…`) — proof the host loaded the + fresh build per invocation. Deterministic on re-run. Evidence: + `s2_negate_run.json`. + +### Task 3 — introspection: --vocabulary / --content-id / --identity-id — WORKS + + aura graph introspect --vocabulary # 2 project + 22 std = 24 lines + aura graph introspect --node momentum_lab::Negate # in value:F64 / out value:F64 + aura graph introspect --content-id < s2_negate.ops.json (A) + aura graph introspect --content-id < s3_negate_renamed.ops.json (B) + aura graph introspect --identity-id < {A,B} + aura graph introspect --content-id --identity-id < A # both, content first + +- `--vocabulary` lists project types first, then std alphabetically; `--node` + resolves a project node's ports. Renamed-twin test (A vs B = same topology, + different node names): content-ids differ (`bd6c70…` vs `9dc729…`), + identity-ids are equal (`b02fbb…`), and the combined flag prints content-id + first — exactly as README / the `identity id` glossary entry document. + Cross-check: `content-id(A)` equals the `topology_hash` stamped in + `s2_negate_run.json`'s manifest. Evidence: `s3_id_comparison.out`. + +### Task 4 — misuse paths a newcomer hits — WORKS (one friction) +- Charter violation (registered a non-`momentum_lab::`-prefixed type id, + rebuilt): refused at load, exit 1, + `aura: project vocabulary rejected: type id ` + "`NoNamespace`" + ` lacks the + project prefix ` + "`momentum_lab::`" + ` — names both sides, house-style prose. + Reverted after capture. Evidence: `s4_charter_violation.err`. +- `--release` with only a debug build: exit 1, names the exact missing path + the + fix (`run cargo build in the project first`). Evidence: `s4_release_missing.err`. +- Outside any project: `--vocabulary` -> std-only (22); a project blueprint is + refused (see Finding F5). Walk-up discovery from a nested subdir + (`momentum-lab/blueprints/`) correctly finds `Aura.toml` (24 entries). + +## Findings + +### [friction] F1 — `aura new` leaves a nested `.git` that snags the enclosing tree +- Task 1. `aura new` runs `git init`; the scaffold contains `momentum-lab/.git`. +- Correct for a real standalone project (C16: "its own git history"). But + `docs/project-layout.md` explicitly supports scaffolding under the engine tree + "before it moves to its own repo" — the exact reason the empty `[workspace]` + table is emitted. That handles cargo's walk-up; nothing handles git's walk-up: + the nested repo becomes an embedded gitlink in the enclosing repo, so + `git add fieldtests/…/momentum-lab` would add a submodule pointer, not the + files. I had to `rm -rf momentum-lab/.git` for the corpus to be committable. +- Recommended: skip `git init` when an enclosing `.git` is detected, or document + the scaffold-under-a-repo wrinkle beside the `[workspace]` note. + +### [doc-gap] F2 — no worked example of a node that reads a bound param +- Task 2. The only authoring template is the scaffolded `Identity` (param-less; + build closure `|_| Box::new(..)`). No public doc (README, project-layout, + ledger, --help) shows how a `PrimitiveBuilder` build closure consumes a bound + param — the natural next step (a tunable, sweepable node). I could author a + param-less node from the surface alone, but a first parametric node cannot be + written from the public docs without reading engine source/rustdoc. +- Recommended: have `aura new` emit one param-bearing node in the template (or + document the build-closure param-read in project-layout.md). Highest-value gap. + +### [doc-gap] F3 — the manifest `project` provenance block is undocumented +- Task 1. The manifest's new `"project":{namespace,dylib_sha256}` block is the + milestone's headline provenance, but the glossary `manifest` entry still + defines a manifest as "(node-commit + params + data-window + seed + broker + profile)" — no `project`. A consumer inspecting the JSON meets an undocumented + field. +- Recommended: add `project` (namespace + dylib hash) to the glossary manifest + definition. + +### [friction] F4 — `run` leaks a raw Rust `Debug` enum for an unknown node type +- Task 4. Same logical error, two phrasings: `graph build` (stdin) -> + `op 5 (add): unknown node type "momentum_lab::Negate"` (exit 1, prose); + `run` (argv file) -> + `aura: s2_negate.bp.json: UnknownNodeType("momentum_lab::Negate")` + (exit 2, raw Debug-formatted enum variant). The exit-code split is correct and + documented (C14: argv-file content = exit 2, stdin data = exit 1), but the + `run` path's `UnknownNodeType("…")` breaks the lowercase house style every other + diagnostic uses. Evidence: `s4_outside_run.err`, `s4_outside_build.err`. +- Recommended: render the loader error on the `run` path in house-style prose + (e.g. `unknown node type "momentum_lab::Negate"`). + +### [doc-gap] F5 — "outside a project" is not distinctly diagnosed +- Task 4. Running a project blueprint with no `Aura.toml` up-tree surfaces the + downstream symptom (`UnknownNodeType`), not the likely cause ("not inside a + project / no Aura.toml found"). A newcomer who cd'd out of their project reads + "unknown node type" rather than "you are not in a project". +- Recommended: when a blueprint names a `namespace::Type` and no project was + discovered, hint that no `Aura.toml` was found up-tree. + +### [doc-gap] F6 — scaffolded `Aura.toml` omits the documented data-archive-root path +- Task 1. Glossary/`project-layout.md` say `Aura.toml` carries "the data archive + root and the runs dir"; the emitted file has only `[paths] runs = "runs"`. No + concrete key name for the data archive root is documented or scaffolded, so a + newcomer wanting `aura run --real ` has no scaffolded slot to point at + their recorded data. Low severity for a synthetic-default v1. +- Recommended: scaffold the data-archive-root key (commented) or drop it from the + Aura.toml prose until a consumer reads it. + +### [working] W1 — the merged-vocabulary authoring loop is real and clean +- Tasks 1-3. Edit lib.rs -> `cargo build` -> the next `aura` invocation loads the + fresh dylib (manifest `dylib_sha256` tracks the rebuild), merges 2 project + 22 + std types, resolves the project node in `graph build`, `run`, and every + `introspect` mode, and produces deterministic runs. Walk-up `Aura.toml` + discovery works from nested subdirs. The whole authoring loop the milestone + promises works end-to-end from the public docs. + +### [working] W2 — id semantics and diagnostics are precise +- Tasks 3-4. `--content-id`/`--identity-id` behave exactly as documented + (name-blind identity id equal across renamed twins; byte-exact content id + differs; combinable, content-first; content-id == manifest `topology_hash`). + The charter refusal and the `--release`-missing message are both clear, + exit-code-correct, and actionable. One micro-nit inside W2's otherwise-great + `--release` message: it says "or pass --release …" even when `--release` was + already passed (the generic hint doesn't adapt to the current mode). + +## Milestone verdict: GREEN + +A downstream consumer can run the entire project-as-crate authoring loop — +`aura new` -> `cargo build` -> run (deterministic, with project provenance) -> +author a real node -> rebuild -> introspect the merged vocabulary -> topology ids +— from the public docs alone, with zero behavioural bugs. All six findings are +friction/doc-gap polish, not loop blockers: + +| Finding | Class | Recommended action | +|---|---|---| +| F1 nested `.git` snags enclosing tree | friction | plan (skip git-init under a repo, or document) | +| F2 no param-node authoring example | doc-gap | plan (scaffold a param node) — highest-value gap | +| F3 manifest `project` block undocumented | doc-gap | tighten glossary | +| F4 `run` leaks Debug enum on unknown type | friction | plan (house-style the loader error) | +| F5 "outside a project" not distinctly diagnosed | doc-gap | plan (hint on missing Aura.toml) | +| F6 Aura.toml data-archive-root un-scaffolded/undocumented | doc-gap | tighten docs | +| W1/W2 loop + id semantics correct | working | carry-on | diff --git a/fieldtests/milestone-project-environment/momentum-lab/.gitignore b/fieldtests/milestone-project-environment/momentum-lab/.gitignore new file mode 100644 index 0000000..af5cf3d --- /dev/null +++ b/fieldtests/milestone-project-environment/momentum-lab/.gitignore @@ -0,0 +1,3 @@ +/target +Cargo.lock +/runs diff --git a/fieldtests/milestone-project-environment/momentum-lab/Aura.toml b/fieldtests/milestone-project-environment/momentum-lab/Aura.toml new file mode 100644 index 0000000..af335c1 --- /dev/null +++ b/fieldtests/milestone-project-environment/momentum-lab/Aura.toml @@ -0,0 +1,3 @@ +# Static project context only (C17); paths only. +[paths] +runs = "runs" diff --git a/fieldtests/milestone-project-environment/momentum-lab/CLAUDE.md b/fieldtests/milestone-project-environment/momentum-lab/CLAUDE.md new file mode 100644 index 0000000..f154dcf --- /dev/null +++ b/fieldtests/milestone-project-environment/momentum-lab/CLAUDE.md @@ -0,0 +1,10 @@ +# momentum-lab — 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 `momentum_lab::` namespace prefix. +- Topology is data (`blueprints/*.json`), node logic is Rust. diff --git a/fieldtests/milestone-project-environment/momentum-lab/Cargo.toml b/fieldtests/milestone-project-environment/momentum-lab/Cargo.toml new file mode 100644 index 0000000..bdfaaf4 --- /dev/null +++ b/fieldtests/milestone-project-environment/momentum-lab/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "momentum-lab" +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] diff --git a/fieldtests/milestone-project-environment/momentum-lab/blueprints/signal.json b/fieldtests/milestone-project-environment/momentum-lab/blueprints/signal.json new file mode 100644 index 0000000..7291f03 --- /dev/null +++ b/fieldtests/milestone-project-environment/momentum-lab/blueprints/signal.json @@ -0,0 +1 @@ +{"format_version":1,"blueprint":{"name":"momentum_lab_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":"momentum_lab::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"}]}} \ No newline at end of file diff --git a/fieldtests/milestone-project-environment/momentum-lab/src/lib.rs b/fieldtests/milestone-project-environment/momentum-lab/src/lib.rs new file mode 100644 index 0000000..08aa32e --- /dev/null +++ b/fieldtests/milestone-project-environment/momentum-lab/src/lib.rs @@ -0,0 +1,127 @@ +//! momentum-lab — an aura research project: node logic + the exported vocabulary. +//! +//! Every node type this crate provides is registered in `vocabulary()` / +//! `type_ids()` under the `momentum_lab::` 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( + "momentum_lab::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 { + 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 { + "momentum_lab::Identity".to_string() + } +} + +/// One-input f64 sign-flip. Emits `-value` (so a downstream consumer can invert a +/// bias). Authored by the fieldtester as the "author your own node" step. +pub struct Negate { + out: [Cell; 1], +} + +impl Negate { + pub fn new() -> Self { + Self { out: [Cell::from_f64(0.0)] } + } + pub fn builder() -> PrimitiveBuilder { + PrimitiveBuilder::new( + "momentum_lab::Negate", + 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(Negate::new()), + ) + } +} + +impl Default for Negate { + fn default() -> Self { + Self::new() + } +} + +impl Node for Negate { + fn lookbacks(&self) -> Vec { + 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 { + "momentum_lab::Negate".to_string() + } +} + +fn vocabulary(type_id: &str) -> Option { + match type_id { + "momentum_lab::Identity" => Some(Identity::builder()), + "momentum_lab::Negate" => Some(Negate::builder()), + _ => None, + } +} + +fn type_ids() -> &'static [&'static str] { + &["momentum_lab::Identity", "momentum_lab::Negate"] +} + +aura_core::aura_project! { + namespace: "momentum_lab", + vocabulary: vocabulary, + type_ids: type_ids, +} diff --git a/fieldtests/milestone-project-environment/s1_starter_run.json b/fieldtests/milestone-project-environment/s1_starter_run.json new file mode 100644 index 0000000..4dd0882 --- /dev/null +++ b/fieldtests/milestone-project-environment/s1_starter_run.json @@ -0,0 +1 @@ +{"manifest":{"commit":"81ac6fd6546da3ba409dd16756043991a43bf702","params":[],"window":[1,18],"seed":0,"broker":"sim-optimal+risk-executor(pip_size=0.0001)","topology_hash":"2a07e310004912835c6743cb646e212074e49c13796b549e46025b7b1513c4b1","project":{"namespace":"momentum_lab","dylib_sha256":"ceda123f75659acdf5ffe6e47a4ffe693068ec48bae5c197a84ec4d15acc8f42"}},"metrics":{"total_pips":0.34185000000002036,"max_drawdown":0.11139999999998655,"bias_sign_flips":2,"r":{"expectancy_r":1.2710005136982836,"n_trades":3,"win_rate":1.0,"avg_win_r":1.2710005136982836,"avg_loss_r":0.0,"profit_factor":0.0,"max_r_drawdown":0.0,"n_open_at_end":1,"sqn":3.141496526818299,"sqn_normalized":3.141496526818299,"net_expectancy_r":1.2710005136982836,"conviction_terciles_r":[0.9285858482198718,2.0771328641652427,0.8072828287097363]}}} diff --git a/fieldtests/milestone-project-environment/s2_negate.bp.json b/fieldtests/milestone-project-environment/s2_negate.bp.json new file mode 100644 index 0000000..15febfd --- /dev/null +++ b/fieldtests/milestone-project-environment/s2_negate.bp.json @@ -0,0 +1 @@ +{"format_version":1,"blueprint":{"name":"graph","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","name":"sub"}},{"primitive":{"type":"Bias","name":"bias","bound":[{"pos":0,"name":"scale","kind":"F64","value":{"F64":0.5}}]}},{"primitive":{"type":"momentum_lab::Negate","name":"neg"}}],"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"}]}} \ No newline at end of file diff --git a/fieldtests/milestone-project-environment/s2_negate.ops.json b/fieldtests/milestone-project-environment/s2_negate.ops.json new file mode 100644 index 0000000..b72c861 --- /dev/null +++ b/fieldtests/milestone-project-environment/s2_negate.ops.json @@ -0,0 +1,14 @@ +[ + {"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":"add","type":"Sub"}, + {"op":"add","type":"Bias","name":"bias","bind":{"scale":{"F64":0.5}}}, + {"op":"add","type":"momentum_lab::Negate","name":"neg"}, + {"op":"feed","role":"price","into":["fast.series","slow.series"]}, + {"op":"connect","from":"fast.value","to":"sub.lhs"}, + {"op":"connect","from":"slow.value","to":"sub.rhs"}, + {"op":"connect","from":"sub.value","to":"bias.signal"}, + {"op":"connect","from":"bias.bias","to":"neg.value"}, + {"op":"expose","from":"neg.value","as":"bias"} +] diff --git a/fieldtests/milestone-project-environment/s2_negate_run.json b/fieldtests/milestone-project-environment/s2_negate_run.json new file mode 100644 index 0000000..3752704 --- /dev/null +++ b/fieldtests/milestone-project-environment/s2_negate_run.json @@ -0,0 +1 @@ +{"manifest":{"commit":"81ac6fd6546da3ba409dd16756043991a43bf702","params":[],"window":[1,18],"seed":0,"broker":"sim-optimal+risk-executor(pip_size=0.0001)","topology_hash":"bd6c70058763140710f268ae5bda6ed8626264213a015686af585a881ae374e8","project":{"namespace":"momentum_lab","dylib_sha256":"70263c832da8457610cfe2fc468f5e7f2a4f156ac29d7be94ca84c3198397e9f"}},"metrics":{"total_pips":-0.34185000000002036,"max_drawdown":0.35860000000001946,"bias_sign_flips":2,"r":{"expectancy_r":-0.6923332538389896,"n_trades":6,"win_rate":0.3333333333333333,"avg_win_r":0.43461244377203523,"avg_loss_r":-1.255806102644502,"profit_factor":0.17304122143411294,"max_r_drawdown":2.8895544571408776,"n_open_at_end":1,"sqn":-1.7371867479561276,"sqn_normalized":-1.7371867479561276,"net_expectancy_r":-0.6923332538389896,"conviction_terciles_r":[-1.3021610224768563,-1.2094511828121481,0.43461244377203523]}}} diff --git a/fieldtests/milestone-project-environment/s3_id_comparison.out b/fieldtests/milestone-project-environment/s3_id_comparison.out new file mode 100644 index 0000000..e579a0b --- /dev/null +++ b/fieldtests/milestone-project-environment/s3_id_comparison.out @@ -0,0 +1,16 @@ +# Scenario 3 — content-id / identity-id across renamed twins (from inside the project) +## A = s2_negate.ops.json (names: fast/slow/sub/bias/neg) +content-id A: bd6c70058763140710f268ae5bda6ed8626264213a015686af585a881ae374e8 + +identity-id A: b02fbb682085cea7cf91c38f4a2e6367a8b4b00b1bb158cba5d1cf48a9252733 + +## B = s3_negate_renamed.ops.json (names: sma_fast/sma_slow/diff/b/inv) +content-id B: 9dc729978b4ddd8da31864a76147bbdb68f6224deab4ab74b84da09931dc0dd6 + +identity-id B: b02fbb682085cea7cf91c38f4a2e6367a8b4b00b1bb158cba5d1cf48a9252733 + +## combined (content-id --identity-id, A) — content first: +bd6c70058763140710f268ae5bda6ed8626264213a015686af585a881ae374e8 +b02fbb682085cea7cf91c38f4a2e6367a8b4b00b1bb158cba5d1cf48a9252733 +## cross-check: content-id(A) vs run-manifest topology_hash(A): +manifest topology_hash: "topology_hash":"bd6c70058763140710f268ae5bda6ed8626264213a015686af585a881ae374e8" diff --git a/fieldtests/milestone-project-environment/s3_negate_renamed.ops.json b/fieldtests/milestone-project-environment/s3_negate_renamed.ops.json new file mode 100644 index 0000000..7c8b00c --- /dev/null +++ b/fieldtests/milestone-project-environment/s3_negate_renamed.ops.json @@ -0,0 +1,14 @@ +[ + {"op":"source","role":"price","kind":"F64"}, + {"op":"add","type":"SMA","name":"sma_fast","bind":{"length":{"I64":2}}}, + {"op":"add","type":"SMA","name":"sma_slow","bind":{"length":{"I64":4}}}, + {"op":"add","type":"Sub","name":"diff"}, + {"op":"add","type":"Bias","name":"b","bind":{"scale":{"F64":0.5}}}, + {"op":"add","type":"momentum_lab::Negate","name":"inv"}, + {"op":"feed","role":"price","into":["sma_fast.series","sma_slow.series"]}, + {"op":"connect","from":"sma_fast.value","to":"diff.lhs"}, + {"op":"connect","from":"sma_slow.value","to":"diff.rhs"}, + {"op":"connect","from":"diff.value","to":"b.signal"}, + {"op":"connect","from":"b.bias","to":"inv.value"}, + {"op":"expose","from":"inv.value","as":"bias"} +] diff --git a/fieldtests/milestone-project-environment/s4_charter_violation.err b/fieldtests/milestone-project-environment/s4_charter_violation.err new file mode 100644 index 0000000..0dda0b6 --- /dev/null +++ b/fieldtests/milestone-project-environment/s4_charter_violation.err @@ -0,0 +1 @@ +aura: project vocabulary rejected: type id `NoNamespace` lacks the project prefix `momentum_lab::` diff --git a/fieldtests/milestone-project-environment/s4_outside_build.err b/fieldtests/milestone-project-environment/s4_outside_build.err new file mode 100644 index 0000000..0e5fa38 --- /dev/null +++ b/fieldtests/milestone-project-environment/s4_outside_build.err @@ -0,0 +1 @@ +aura: op 5 (add): unknown node type "momentum_lab::Negate" diff --git a/fieldtests/milestone-project-environment/s4_outside_run.err b/fieldtests/milestone-project-environment/s4_outside_run.err new file mode 100644 index 0000000..61a229f --- /dev/null +++ b/fieldtests/milestone-project-environment/s4_outside_run.err @@ -0,0 +1 @@ +aura: s2_negate.bp.json: UnknownNodeType("momentum_lab::Negate") diff --git a/fieldtests/milestone-project-environment/s4_release_missing.err b/fieldtests/milestone-project-environment/s4_release_missing.err new file mode 100644 index 0000000..654b6fd --- /dev/null +++ b/fieldtests/milestone-project-environment/s4_release_missing.err @@ -0,0 +1 @@ +aura: project dylib not found at /home/brummel/dev/aura/fieldtests/milestone-project-environment/momentum-lab/target/release/libmomentum_lab.so — run `cargo build` in the project first (or pass --release to load the release build)