fieldtest: milestone safe-to-embed — 4 examples, 4 bugs / 4 friction / 2 spec-gaps / 6 working

Source-blind milestone fieldtest of the embedding promise (range
024e865..32f6be8): a path-dep World program driving refusals as values
and a live in-process tap, reproduce-as-data with both guard classes and
a tampered-metric divergence probe, 22 CLI exit-class probes derived
from the docs beforehand, and the stale-dylib handshake via the nodes-new
scaffold plus a rev-pinned external crate. Replayable via m4_0_run_all.sh.

Findings: 2 code bugs fixed in-cycle RED-first (99e9300 — the library
exposes-neither panic was the one real promise breach), 2 doc bugs fixed
in the same commit, 4 friction items bundled as #349, 2 spec gaps
ratified into C30 (rev+lockfile clause; the scaffold's absolute path also
in #349 — the committed lab-nodes fixture is relativized), 6 working.

refs #296
This commit is contained in:
2026-07-26 20:06:18 +02:00
parent 99e93000c5
commit 9636b00314
29 changed files with 3444 additions and 0 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,18 @@
[package]
name = "embed-host"
version = "0.0.0"
edition = "2021"
publish = false
# A node crate is its own workspace (docs/project-layout.md); an external
# embedding under the engine checkout hits the same cargo trap, so the same
# empty table applies here.
[workspace]
# C30 point 2: an external embedding in its own repo pins the engine as a git
# dependency at a rev. This fixture lives INSIDE the engine checkout, so it
# uses the path form of the same edge — the node-crate mechanism.
[dependencies]
aura-core = { path = "../../../crates/aura-core" }
aura-engine = { path = "../../../crates/aura-engine" }
aura-runner = { path = "../../../crates/aura-runner" }
@@ -0,0 +1,123 @@
//! Fieldtest, milestone 39 (safe to embed), axis 1 — the embedding consumer.
//!
//! A downstream "World program": it runs one signal blueprint through the
//! engine's library surface (no `aura` binary involved), drains one tap
//! in-process, and then deliberately walks into three refusals — one
//! argv-named-content class, one environment class, one tap-name class.
//! The promise under test: every refusal comes back as a `RunnerError`
//! VALUE, the host keeps running, and the host itself decides what to do
//! with the exit class.
//!
//! Run it from inside the scaffolded project: `cd lab && cargo run
//! --manifest-path ../embed-host/Cargo.toml --bin m4_1_refusals_are_values`.
use aura_engine::blueprint_from_json;
use aura_runner::member::{run_signal_r, RunData};
use aura_runner::project;
use aura_runner::tap_plan::{TapPlan, TapSubscription};
use aura_runner::RunnerError;
use std::path::Path;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
fn main() {
let root = project::discover_from(Path::new("."))
.expect("run this from inside a project (an Aura.toml directory)");
let penv = project::load(&root, false).expect("data-only project loads");
let env = project::Env::with_project(penv);
let doc = std::fs::read_to_string(root.join("blueprints/embed-probe.json"))
.expect("the op-script-built blueprint is on disk");
let load = |env: &project::Env| {
blueprint_from_json(&doc, &|type_id| env.resolve(type_id))
.expect("blueprint parses against the project vocabulary")
};
// ---- 1. the happy path, with the tap drained IN PROCESS -------------
let seen = Arc::new(AtomicUsize::new(0));
let counter = Arc::clone(&seen);
let mut plan = TapPlan::empty();
plan.subscribe(
"spread",
TapSubscription::live(move |_ts, _cell| {
counter.fetch_add(1, Ordering::Relaxed);
}),
);
match run_signal_r(load(&env), &[], RunData::Synthetic, 0, &env, plan, None) {
Ok((report, notes)) => println!(
"[1] ok: {} tap samples reached this process, notes={:?}\n manifest.topology_hash={:?}",
seen.load(Ordering::Relaxed),
notes,
report.manifest.topology_hash
),
Err(e) => println!("[1] UNEXPECTED refusal: exit {}{}", e.exit_code, e.message),
}
// ---- 2. a fold label the registry does not carry --------------------
let mut plan = TapPlan::empty();
plan.subscribe("spread", TapSubscription::named("median"));
report_refusal(
"[2] unknown fold label (argv-named content -> expect class 2)",
run_signal_r(load(&env), &[], RunData::Synthetic, 0, &env, plan, None),
);
// ---- 3. a tap name the blueprint does not declare -------------------
let mut plan = TapPlan::empty();
plan.subscribe("spred", TapSubscription::named("mean"));
report_refusal(
"[3] unknown tap name (argv-named content -> expect class 2)",
run_signal_r(load(&env), &[], RunData::Synthetic, 0, &env, plan, None),
);
// ---- 4. a symbol the archive does not have --------------------------
let data = RunData::Real {
symbol: "NOSUCHSYMBOL".to_string(),
from: None,
to: None,
};
report_refusal(
"[4] symbol absent from the archive (environment -> expect class 1)",
run_signal_r(load(&env), &[], data, 0, &env, TapPlan::empty(), None),
);
// ---- 5. the success path: does the library print into MY stdout? ----
println!("[5] --- begin record_all run; anything between here and [5-end] is not mine");
match run_signal_r(
load(&env),
&[],
RunData::Synthetic,
0,
&env,
TapPlan::record_all(),
None,
) {
Ok((_, notes)) => println!("[5-end] ok, returned notes={notes:?}"),
Err(e) => println!("[5-end] refused: exit {}{}", e.exit_code, e.message),
}
// ---- 6..8. refusals the CLI reports as class 2 on this same leg -----
// Do they reach an embedder as VALUES too, or only as CLI-side checks?
// NOTE (fieldtest run, 2026-07-26): step [8] never printed — the call
// panicked inside the library and took this host down with exit 101.
for (label, file) in [
("[6] open blueprint, free knobs", "blueprints/open-probe.json"),
("[7] root role no column binds", "blueprints/unbindable-probe.json"),
("[8] exposes neither bias nor tap", "blueprints/blind-probe.json"),
] {
let src = std::fs::read_to_string(root.join(file)).expect("fixture on disk");
let bp = blueprint_from_json(&src, &|t| env.resolve(t)).expect("parses");
report_refusal(
label,
run_signal_r(bp, &[], RunData::Synthetic, 0, &env, TapPlan::empty(), None),
);
}
println!("[host] still alive after 3 refusals — the milestone promise holds");
}
fn report_refusal<T>(what: &str, outcome: Result<T, RunnerError>) {
match outcome {
Ok(_) => println!("{what}\n UNEXPECTED: ran to completion, no refusal"),
Err(e) => println!("{what}\n exit_code={} message={:?}", e.exit_code, e.message),
}
}
@@ -0,0 +1,63 @@
//! Fieldtest, milestone 39 (safe to embed), axis 1 — reproduce as a value.
//!
//! The downstream task: a World program wants to re-verify a persisted
//! family before building on it — "is this stored result still the result
//! this engine produces?" — and wants the answer as DATA, not as a process
//! exit. It then walks into the two mismatch-guard classes: an explicit
//! source that contradicts the stored members (caller's fault, class 2) and
//! an id nothing is stored under (environment, class 1).
//!
//! Usage: `cd lab && cargo run --manifest-path ../embed-host/Cargo.toml \
//! --bin m4_2_reproduce_as_data -- <family-id>`
use aura_runner::family::{DataChoice, DataSource};
use aura_runner::project;
use aura_runner::reproduce::{reproduce_family, reproduce_family_in};
use std::path::Path;
fn main() {
let id = std::env::args().nth(1).expect("usage: <family-id>");
let root = project::discover_from(Path::new(".")).expect("run inside the project");
let penv = project::load(&root, false).expect("data-only project loads");
let env = project::Env::with_project(penv);
// ---- 1. the answer is a report, divergence included -----------------
match reproduce_family(&id, &env) {
Ok(report) => {
println!("[1] reproduce_family -> Ok, all_identical={}", report.all_identical());
for (member, identical) in &report.outcomes {
println!(" {member} -> bit-identical={identical}");
}
}
Err(e) => println!("[1] refused: exit_code={} message={:?}", e.exit_code, e.message),
}
// ---- 2. explicit source contradicting the stored members ------------
// The family above was recorded over GER40; hand it EURUSD instead.
let wrong = DataSource::from_choice(
DataChoice::Real { symbol: "EURUSD".to_string(), from_ms: None, to_ms: None },
&env,
)
.expect("EURUSD has recorded geometry");
match reproduce_family_in(&env.registry(), &id, &wrong, &env) {
Ok(report) => println!(
"[2] UNEXPECTED: ran against the wrong instrument, all_identical={}",
report.all_identical()
),
Err(e) => println!(
"[2] explicit-source mismatch (expect class 2): exit_code={} message={:?}",
e.exit_code, e.message
),
}
// ---- 3. an id nothing is stored under -------------------------------
match reproduce_family("no-such-family-0", &env) {
Ok(_) => println!("[3] UNEXPECTED: reproduced a family that does not exist"),
Err(e) => println!(
"[3] unknown family id (expect class 1): exit_code={} message={:?}",
e.exit_code, e.message
),
}
println!("[host] still alive — reproduce never took the process down");
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,15 @@
[package]
name = "external-embed"
version = "0.0.0"
edition = "2021"
publish = false
[workspace]
# C30 point 2, consumer class 2: "an external embedding (a World program in
# its own repo) consumes the workspace crates as a cargo git dependency
# pinned to a rev." This is that mechanism, exercised literally — the rev is
# the newest commit published on origin/main at fieldtest time.
[dependencies]
aura-runner = { git = "http://192.168.178.103:3000/Brummel/Aura.git", rev = "024e8652c0afc186b2718c0c0f5189a6874fa5d7" }
aura-engine = { git = "http://192.168.178.103:3000/Brummel/Aura.git", rev = "024e8652c0afc186b2718c0c0f5189a6874fa5d7" }
@@ -0,0 +1,18 @@
//! Fieldtest, milestone 39, axis 3 — the external-embedding mechanism.
//!
//! The smallest possible World program of C30's second consumer class: it
//! does not live in the engine checkout and does not use the `aura` binary;
//! it pins the engine at a rev and calls the library. All it has to do to
//! count is BUILD and reach one library entry point.
use aura_runner::project::Env;
fn main() {
let env = Env::std();
let types = env.type_ids();
println!(
"external embedding alive: {} node types visible, runs root {:?}",
types.len(),
env.runs_root()
);
}
@@ -0,0 +1,2 @@
/target
Cargo.lock
@@ -0,0 +1,11 @@
# lab-nodes — an aura node crate
Native node logic for an aura research project (extension-dev role). This
crate is attached to its project via `[nodes]` in the project's `Aura.toml`.
- Build: `cargo build` (the next `aura` invocation in the project loads the
fresh dylib)
- Each node is registered in `vocabulary()`/`type_ids()` under the
`lab_nodes::` namespace prefix; blueprints reference nodes by that id.
- This crate has no data-plane dependencies — nodes are pure stream
transformers over read-only input windows.
@@ -0,0 +1,17 @@
[package]
name = "lab-nodes"
version = "0.1.0"
edition = "2024"
publish = false
[lib]
crate-type = ["cdylib"]
[dependencies]
# The scaffold emits an ABSOLUTE engine path here (fieldtest finding S2);
# relativized for the committed corpus so the fixture survives the
# worktree it was minted in.
aura-core = { path = "../../../crates/aura-core" }
# Standalone workspace root: never a member of an enclosing workspace.
[workspace]
@@ -0,0 +1,77 @@
//! lab-nodes — an aura research project: node logic + the exported vocabulary.
//!
//! Every node type this crate provides is registered in `vocabulary()` /
//! `type_ids()` under the `lab_nodes::` 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, ParamSpec, PortSpec, PrimitiveBuilder,
ScalarKind,
};
/// One-input scalar gain: emits `input * factor`. Emits `None` until its
/// input has a value (warm-up filter, C8).
pub struct Scale {
factor: f64,
out: [Cell; 1],
}
impl Scale {
pub fn new(factor: f64) -> Self {
Self { factor, out: [Cell::from_f64(0.0)] }
}
// Replace `doc` below when renaming this sample node — it must keep
// describing the node's own behaviour, not this scaffolding step.
pub fn builder() -> PrimitiveBuilder {
PrimitiveBuilder::new(
"lab_nodes::Scale",
NodeSchema {
inputs: vec![PortSpec {
kind: ScalarKind::F64,
firing: Firing::Any,
name: "value".into(),
}],
output: vec![FieldSpec { name: "value".into(), kind: ScalarKind::F64 }],
params: vec![ParamSpec { name: "factor".into(), kind: ScalarKind::F64 }],
// C29: every vocabulary entry ships a one-line meaning — the
// doc field is required (E0063 without it) and gated at load.
doc: "scalar gain: emits the input times the factor param",
},
|p| Box::new(Scale::new(p[0].f64())),
)
}
}
impl Node for Scale {
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] * self.factor);
Some(&self.out)
}
fn label(&self) -> String {
format!("lab_nodes::Scale({})", self.factor)
}
}
fn vocabulary(type_id: &str) -> Option<PrimitiveBuilder> {
match type_id {
"lab_nodes::Scale" => Some(Scale::builder()),
_ => None,
}
}
fn type_ids() -> &'static [&'static str] {
&["lab_nodes::Scale"]
}
aura_core::aura_project! {
namespace: "lab_nodes",
vocabulary: vocabulary,
type_ids: type_ids,
}
@@ -0,0 +1 @@
/runs
@@ -0,0 +1,7 @@
# Static project context only (C17); paths only.
[paths]
runs = "runs"
# data = "/path/to/archive" # the recorded-data root; defaults to the built-in path
[nodes]
crates = ["../lab-nodes"]
@@ -0,0 +1,24 @@
# lab — 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 <campaign.json>` 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 `<node>.<param>` names (#328)
- Native nodes: when the project needs its first project-specific node,
`aura nodes new <name>` 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`.
@@ -0,0 +1 @@
{"format_version":1,"blueprint":{"name":"blind-probe","doc":"the same graph with neither a bias output nor a declared tap","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"}]}}
@@ -0,0 +1 @@
{"format_version":1,"blueprint":{"name":"embed-probe","doc":"fast/slow SMA spread clamped to a bias, with the raw spread tapped","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}}]}}
@@ -0,0 +1 @@
{"format_version":1,"blueprint":{"name":"open-probe","doc":"the same spread-to-bias signal with every knob left open","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"}],"taps":[{"name":"spread","from":{"node":2,"field":0}}]}}
@@ -0,0 +1 @@
{"format_version":1,"blueprint":{"name":"lab_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"}]}}
@@ -0,0 +1 @@
{"format_version":1,"blueprint":{"name":"unbindable-probe","doc":"the same signal fed by a root role no archive column carries","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":"sentiment","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}}]}}
@@ -0,0 +1,56 @@
#!/usr/bin/env bash
# Fieldtest, milestone 39 ("safe to embed") — the whole session, replayed.
#
# Reproduces every example in this directory from a clean checkout, in the
# order a downstream consumer met them. Run it from THIS directory:
#
# bash m4_0_run_all.sh
#
# Prerequisites: `cargo build --workspace --release` at the repo root, the
# Pepperstone archive mounted (GER40 M1 for Sep 2024), and — for example 4's
# stale-dylib probe — `git worktree add --detach /tmp/aura-stale d87f534`.
set -u
HERE=$(cd "$(dirname "$0")" && pwd)
AURA=$HERE/../../target/release/aura
cd "$HERE"
[ -d lab ] || $AURA new lab
cd lab
echo "=== build the fixtures (canonical authoring form: op-scripts) ==="
for s in tapped open blind unbindable; do
case $s in
tapped) src=m4_1_tapped_signal.ops.json; out=embed-probe.json ;;
open) src=m4_1_open_signal.ops.json; out=open-probe.json ;;
blind) src=m4_1_blind_signal.ops.json; out=blind-probe.json ;;
unbindable) src=m4_1_unbindable_signal.ops.json; out=unbindable-probe.json ;;
esac
$AURA graph build < "../$src" > "blueprints/$out" || echo "graph build failed for $src"
done
$AURA graph register blueprints/embed-probe.json
echo
echo "=== example 1 — refusals are values (library face) ==="
cargo run -q --manifest-path ../embed-host/Cargo.toml --bin m4_1_refusals_are_values
echo "host exit: $?"
echo
echo "=== example 2 — reproduce returns its report ==="
$AURA process register ../m4_2_process_sweep_only.json
$AURA campaign register ../m4_2_campaign_ger40.json
$AURA exec ../m4_2_campaign_ger40.json > /dev/null
FAMILY=$($AURA runs families | tail -1 | sed 's/.*"family_id":"\([^"]*\)".*/\1/')
echo "family: $FAMILY"
cargo run -q --manifest-path ../embed-host/Cargo.toml --bin m4_2_reproduce_as_data -- "$FAMILY"
bash ../m4_2_divergence_probe.sh "$FAMILY"
echo
echo "=== example 3 — the CLI exit-class partition ==="
bash ../m4_3_exit_classes.sh
echo
echo "=== example 4 — the compatibility contract ==="
$AURA nodes new lab-nodes 2>/dev/null || echo "(node crate already attached)"
bash ../m4_4_stale_dylib_probe.sh
echo "--- and the external, rev-pinned embedding:"
( cd ../external-embed && CARGO_TARGET_DIR=/tmp/m4-ext-target cargo run -q )
@@ -0,0 +1,73 @@
[
{
"op": "name",
"name": "blind-probe"
},
{
"op": "doc",
"text": "the same graph with neither a bias output nor a declared tap"
},
{
"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"
}
]
@@ -0,0 +1,68 @@
[
{
"op": "name",
"name": "open-probe"
},
{
"op": "doc",
"text": "the same spread-to-bias signal with every knob left open"
},
{
"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": "tap",
"from": "sub.value",
"as": "spread"
},
{
"op": "expose",
"from": "bias.bias",
"as": "bias"
}
]
@@ -0,0 +1,15 @@
[
{"op": "name", "name": "embed-probe"},
{"op": "doc", "text": "fast/slow SMA spread clamped to a bias, with the raw spread tapped"},
{"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"}
]
@@ -0,0 +1,83 @@
[
{
"op": "name",
"name": "unbindable-probe"
},
{
"op": "doc",
"text": "the same signal fed by a root role no archive column carries"
},
{
"op": "source",
"role": "sentiment",
"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": "sentiment",
"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"
}
]
@@ -0,0 +1,20 @@
{
"format_version": 1,
"kind": "campaign",
"name": "m4-embed-reproduce-probe",
"seed": 7,
"data": {
"instruments": ["GER40"],
"windows": [ { "from_ms": 1725148800000, "to_ms": 1725753600000 } ]
},
"strategies": [
{
"ref": { "content_id": "00fd2bc044fe4c9b947aac97da740e6d08bf4103ec376058f0cf52590f7863aa" },
"axes": {
"fast.length": { "kind": "I64", "values": [2, 3] }
}
}
],
"process": { "ref": { "content_id": "e4a97c684686c2982f034a27dabb7f26e54c76d7578dd985eaa41ef67c77f275" } },
"presentation": { "persist_taps": [], "emit": ["family_table"] }
}
@@ -0,0 +1,45 @@
#!/usr/bin/env bash
# Fieldtest, milestone 39, axis 1 — divergence must come back as DATA.
#
# A downstream consumer's realistic worry: the stored family in the registry
# was recorded by a different engine state, so re-deriving it no longer
# matches. We simulate exactly that observable — a stored metric that the
# re-run does not reproduce — by editing the run registry's stored value
# (the registry is a plain JSONL artifact, C18), then asking both faces the
# same question: the embedding library and the `aura` binary.
#
# Run from the `lab/` project directory.
set -u
AURA=${AURA:-../../../target/release/aura}
FAMILY=${1:-ff72bba2-0-GER40-w0-r0-s0-0}
STORE=runs/families.jsonl
cp "$STORE" "$STORE.orig"
python3 - "$STORE" "$FAMILY" <<'PY'
import json, sys
p, handle = sys.argv[1], sys.argv[2]
family, run = handle.rsplit("-", 1)
lines = open(p).read().splitlines()
for i, line in enumerate(lines):
d = json.loads(line)
if d["family"] == family and str(d["run"]) == run and d["ordinal"] == 0:
# nudge one stored metric of member 0 — nothing else
d["report"]["metrics"]["r"]["expectancy_r"] += 1.0
lines[i] = json.dumps(d)
break
else:
sys.exit(f"no member 0 of {handle} in {p}")
open(p, "w").write("\n".join(lines) + "\n")
PY
echo "--- tampered: member 0's stored expectancy_r shifted by +1.0"
echo "--- library face (embedding host):"
cargo run -q --manifest-path ../embed-host/Cargo.toml --bin m4_2_reproduce_as_data -- "$FAMILY" 2>&1 | sed -n '1,4p'
echo " host exit: $?"
echo "--- CLI face:"
"$AURA" reproduce "$FAMILY"
echo " cli exit: $?"
mv "$STORE.orig" "$STORE"
echo "--- restored"
@@ -0,0 +1,7 @@
{
"format_version": 1,
"kind": "process",
"name": "m4-explore-only-sweep",
"description": "Selection-free sweep: the family itself is the result — the smallest thing that persists a reproducible family.",
"pipeline": [ { "block": "std::sweep" } ]
}
@@ -0,0 +1,89 @@
#!/usr/bin/env bash
# Fieldtest, milestone 39, axis 2 — the CLI exit-class partition.
#
# The downstream task: I am writing a CI wrapper around `aura` and I want to
# branch on the failure CLASS without parsing stderr, exactly as C14 promises
# (2 = the content of what argv named, 1 = the environment/recorded state,
# 3 = campaign completed with failed cells, 0 = success). Every probe below
# is a refusal a real author trips over; `want` is the class I derived from
# docs/authoring-guide.md's exit-code passage + C14 BEFORE running it.
#
# Run from the `lab/` project directory.
set -u
AURA=${AURA:-../../../target/release/aura}
BP=blueprints/embed-probe.json
tmp=$(mktemp -d)
pass=0; fail=0
probe() { # probe <want> <label> -- <cmd...>
local want=$1 label=$2; shift 3
local out; out=$("$@" 2>&1 >/dev/null); local got=$?
local verdict="OK "; if [ "$got" != "$want" ]; then verdict="DIFF"; fi
if [ "$got" = "$want" ]; then pass=$((pass+1)); else fail=$((fail+1)); fi
printf '%s want=%s got=%s %-46s | %s\n' "$verdict" "$want" "$got" "$label" "$(echo "$out" | head -1)"
}
# --- 0: success -------------------------------------------------------------
probe 0 "closed blueprint, one synthetic run" -- $AURA exec $BP
probe 0 "blueprint + declared tap folded" -- $AURA exec $BP --tap spread=mean
# --- 2: the content of what argv named --------------------------------------
printf 'not json at all\n' > "$tmp/notjson.json"
probe 2 "target file is not JSON" -- $AURA exec "$tmp/notjson.json"
cp ../m4_1_tapped_signal.ops.json "$tmp/oplist.json"
probe 2 "op-script array handed to exec" -- $AURA exec "$tmp/oplist.json"
probe 2 "process document handed to exec" -- $AURA exec ../m4_2_process_sweep_only.json
printf '{"format_version":1,"blueprint":{"nodes":[],"edges":[]}}\n' > "$tmp/broken.json"
probe 2 "blueprint envelope that will not build" -- $AURA exec "$tmp/broken.json"
python3 - <<PY
import json
ops = json.load(open("../m4_1_tapped_signal.ops.json"))
op = [dict(o) for o in ops]
for o in op:
o.pop("bind", None)
if o.get("op") == "name": o["name"] = "open-probe"
json.dump(op, open("$tmp/open.ops.json", "w"))
bl = [o for o in ops if o.get("op") not in ("expose", "tap")]
for o in bl:
if o.get("op") == "name": o["name"] = "blind-probe"
json.dump(bl, open("$tmp/blind.ops.json", "w"))
PY
$AURA graph build < "$tmp/open.ops.json" > "$tmp/open.bp.json"
$AURA graph build < "$tmp/blind.ops.json" > "$tmp/blind.bp.json"
probe 2 "open blueprint (free knobs) run directly" -- $AURA exec "$tmp/open.bp.json"
probe 2 "blueprint exposing neither bias nor tap" -- $AURA exec "$tmp/blind.bp.json"
probe 2 "unknown fold label on a declared tap" -- $AURA exec $BP --tap spread=median
probe 2 "tap name the blueprint does not declare" -- $AURA exec $BP --tap spred=mean
probe 2 "same tap subscribed twice" -- $AURA exec $BP --tap spread=mean --tap spread=count
probe 2 "override token with no '='" -- $AURA exec $BP --override fast.length
probe 2 "override value that is not a literal" -- $AURA exec $BP --override fast.length=abc
probe 2 "override names no param of the graph" -- $AURA exec $BP --override nope.length=3
probe 2 "override value of the wrong kind" -- $AURA exec $BP --override fast.length=1.5
# --- 1: the environment / recorded state ------------------------------------
BPID=00fd2bc044fe4c9b947aac97da740e6d08bf4103ec376058f0cf52590f7863aa
PRID=e4a97c684686c2982f034a27dabb7f26e54c76d7578dd985eaa41ef67c77f275
# same campaign as axis 1, but a window the archive cannot serve (year 2124)
sed -e 's/"from_ms": 1725148800000/"from_ms": 4870281600000/' \
-e 's/"to_ms": 1725753600000/"to_ms": 4870886400000/' \
-e 's/"name": "m4-embed-reproduce-probe"/"name": "m4-window-with-no-data"/' \
../m4_2_campaign_ger40.json > "$tmp/nodata.json"
# ... one over an instrument the archive has never heard of
sed -e 's/"GER40"/"NOSUCHSYM"/' \
-e 's/"name": "m4-embed-reproduce-probe"/"name": "m4-absent-symbol"/' \
../m4_2_campaign_ger40.json > "$tmp/absent.json"
# ... and one whose axis carries no values at all
sed -e 's/"values": \[2, 3\]/"values": []/' \
-e 's/"name": "m4-embed-reproduce-probe"/"name": "m4-empty-axis"/' \
../m4_2_campaign_ger40.json > "$tmp/emptyaxis.json"
probe 1 "override value out of the node's domain" -- $AURA exec $BP --override fast.length=-1
probe 1 "target is neither file nor content id" -- $AURA exec no-such-target
probe 1 "well-formed but unregistered content id" -- $AURA exec 0000000000000000000000000000000000000000000000000000000000000000
probe 1 "reproduce an unknown family id" -- $AURA reproduce no-such-family-0
probe 1 "campaign over a window the archive lacks" -- $AURA exec "$tmp/nodata.json"
probe 1 "campaign over a symbol the archive lacks" -- $AURA exec "$tmp/absent.json"
probe 1 "campaign document content fails its gate" -- $AURA exec "$tmp/emptyaxis.json"
echo "--- $pass matched the class I derived from the docs, $fail did not"
rm -rf "$tmp"
@@ -0,0 +1,36 @@
#!/usr/bin/env bash
# Fieldtest, milestone 39, axis 3 — the compatibility contract (C30).
#
# The downstream scenario C30 point 3 describes: my node crate rides the
# engine checkout as a path dep, I pull a newer engine, and my previously
# built cdylib is now stale. The contract promises the load handshake
# refuses it ("a dylib from any other engine state is refused at load, never
# trusted") instead of trusting a frozen version stamp.
#
# Simulated the only way a consumer can simulate it without touching engine
# sources: a second checkout of the engine at an older commit
# (`git worktree add --detach /tmp/aura-stale d87f534`, the commit right
# before #348 re-armed the stamp), the node crate rebuilt against THAT
# aura-core, and the current host asked to load the result.
#
# Run from the `lab/` project directory.
set -u
AURA=${AURA:-../../../target/release/aura}
STALE=${STALE:-/tmp/aura-stale}
NODES=../lab-nodes
echo "--- baseline: node crate built against the checkout it is attached to"
( cd $NODES && cargo build -q 2>&1 | tail -2 )
$AURA graph introspect --node lab_nodes::Scale
echo " exit: $?"
echo "--- now rebuild the very same node crate against $STALE (an older engine state)"
cp $NODES/Cargo.toml $NODES/Cargo.toml.orig
sed -i "s#path = \"[^\"]*crates/aura-core\"#path = \"$STALE/crates/aura-core\"#" $NODES/Cargo.toml
( cd $NODES && cargo build -q 2>&1 | tail -3 )
$AURA graph introspect --node lab_nodes::Scale
echo " exit: $?"
mv $NODES/Cargo.toml.orig $NODES/Cargo.toml
( cd $NODES && cargo build -q 2>&1 | tail -1 )
echo "--- restored"