From 2d988fdf3dd883b6d201e70749ca7d8e7702ed4a Mon Sep 17 00:00:00 2001 From: claude Date: Thu, 23 Jul 2026 20:55:21 +0200 Subject: [PATCH] =?UTF-8?q?fieldtest:=20316-self-description=20=E2=80=94?= =?UTF-8?q?=204=20examples,=201=20bug=20/=203=20friction=20/=201=20spec-ga?= =?UTF-8?q?p?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consumer-seat run over all four C29 seams (load, register, op-script doc, document description) from the public interface only. The three working findings verify the #314 failure class removed end to end; the findings route: guide sync + refusal-prose neutrality + doc_gate short-name parity this run, discoverability surfaces to the tracker. refs #316 --- .../c316_1_scale_extension.bp.json | 1 + .../c316_1_scale_extension.ops.json | 8 ++ .../c316_2_smacross_nodoc.bp.json | 1 + .../c316_2_smacross_nodoc.ops.json | 12 +++ .../c316_3_smacross_doc.bp.json | 1 + .../c316_3_smacross_doc.ops.json | 13 ++++ .../c316_4_campaign_empty.json | 11 +++ .../c316_4_campaign_good.json | 11 +++ .../c316_4_campaign_nodesc.json | 11 +++ .../c316_4_campaign_restate.json | 11 +++ .../c316_4_process_empty.json | 7 ++ .../c316_4_process_good.json | 7 ++ .../c316_4_process_restate.json | 7 ++ .../lab316-nodes/.gitignore | 2 + .../lab316-nodes/CLAUDE.md | 11 +++ .../lab316-nodes/Cargo.toml | 14 ++++ .../lab316-nodes/src/lib.rs | 75 +++++++++++++++++++ .../lab316/.gitignore | 1 + .../lab316/Aura.toml | 7 ++ .../lab316/CLAUDE.md | 14 ++++ .../lab316/blueprints/signal.json | 1 + 21 files changed, 226 insertions(+) create mode 100644 fieldtests/cycle-316-self-description/c316_1_scale_extension.bp.json create mode 100644 fieldtests/cycle-316-self-description/c316_1_scale_extension.ops.json create mode 100644 fieldtests/cycle-316-self-description/c316_2_smacross_nodoc.bp.json create mode 100644 fieldtests/cycle-316-self-description/c316_2_smacross_nodoc.ops.json create mode 100644 fieldtests/cycle-316-self-description/c316_3_smacross_doc.bp.json create mode 100644 fieldtests/cycle-316-self-description/c316_3_smacross_doc.ops.json create mode 100644 fieldtests/cycle-316-self-description/c316_4_campaign_empty.json create mode 100644 fieldtests/cycle-316-self-description/c316_4_campaign_good.json create mode 100644 fieldtests/cycle-316-self-description/c316_4_campaign_nodesc.json create mode 100644 fieldtests/cycle-316-self-description/c316_4_campaign_restate.json create mode 100644 fieldtests/cycle-316-self-description/c316_4_process_empty.json create mode 100644 fieldtests/cycle-316-self-description/c316_4_process_good.json create mode 100644 fieldtests/cycle-316-self-description/c316_4_process_restate.json create mode 100644 fieldtests/cycle-316-self-description/lab316-nodes/.gitignore create mode 100644 fieldtests/cycle-316-self-description/lab316-nodes/CLAUDE.md create mode 100644 fieldtests/cycle-316-self-description/lab316-nodes/Cargo.toml create mode 100644 fieldtests/cycle-316-self-description/lab316-nodes/src/lib.rs create mode 100644 fieldtests/cycle-316-self-description/lab316/.gitignore create mode 100644 fieldtests/cycle-316-self-description/lab316/Aura.toml create mode 100644 fieldtests/cycle-316-self-description/lab316/CLAUDE.md create mode 100644 fieldtests/cycle-316-self-description/lab316/blueprints/signal.json diff --git a/fieldtests/cycle-316-self-description/c316_1_scale_extension.bp.json b/fieldtests/cycle-316-self-description/c316_1_scale_extension.bp.json new file mode 100644 index 0000000..1577ce9 --- /dev/null +++ b/fieldtests/cycle-316-self-description/c316_1_scale_extension.bp.json @@ -0,0 +1 @@ +{"format_version":1,"blueprint":{"name":"graph","nodes":[{"primitive":{"type":"lab316_nodes::Scale","name":"scaled","bound":[{"pos":0,"name":"factor","kind":"F64","value":{"F64":2.0}}]}},{"primitive":{"type":"Bias","name":"bias","bound":[{"pos":0,"name":"scale","kind":"F64","value":{"F64":1.0}}]}}],"edges":[{"from":0,"to":1,"slot":0,"from_field":0}],"input_roles":[{"name":"price","targets":[{"node":0,"slot":0}],"source":"F64"}],"output":[{"node":1,"field":0,"name":"bias"}]}} \ No newline at end of file diff --git a/fieldtests/cycle-316-self-description/c316_1_scale_extension.ops.json b/fieldtests/cycle-316-self-description/c316_1_scale_extension.ops.json new file mode 100644 index 0000000..357c18f --- /dev/null +++ b/fieldtests/cycle-316-self-description/c316_1_scale_extension.ops.json @@ -0,0 +1,8 @@ +[ + {"op": "source", "role": "price", "kind": "F64"}, + {"op": "add", "type": "lab316_nodes::Scale", "name": "scaled", "bind": {"factor": {"F64": 2.0}}}, + {"op": "feed", "role": "price", "into": ["scaled.value"]}, + {"op": "add", "type": "Bias", "name": "bias", "bind": {"scale": {"F64": 1.0}}}, + {"op": "connect", "from": "scaled.value", "to": "bias.signal"}, + {"op": "expose", "from": "bias.bias", "as": "bias"} +] diff --git a/fieldtests/cycle-316-self-description/c316_2_smacross_nodoc.bp.json b/fieldtests/cycle-316-self-description/c316_2_smacross_nodoc.bp.json new file mode 100644 index 0000000..83ba539 --- /dev/null +++ b/fieldtests/cycle-316-self-description/c316_2_smacross_nodoc.bp.json @@ -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"}]}} \ No newline at end of file diff --git a/fieldtests/cycle-316-self-description/c316_2_smacross_nodoc.ops.json b/fieldtests/cycle-316-self-description/c316_2_smacross_nodoc.ops.json new file mode 100644 index 0000000..ccbeb1a --- /dev/null +++ b/fieldtests/cycle-316-self-description/c316_2_smacross_nodoc.ops.json @@ -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"} +] diff --git a/fieldtests/cycle-316-self-description/c316_3_smacross_doc.bp.json b/fieldtests/cycle-316-self-description/c316_3_smacross_doc.bp.json new file mode 100644 index 0000000..496fe6b --- /dev/null +++ b/fieldtests/cycle-316-self-description/c316_3_smacross_doc.bp.json @@ -0,0 +1 @@ +{"format_version":1,"blueprint":{"name":"graph","doc":"fast/slow SMA crossover spread turned into a bounded directional bias","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"}]}} \ No newline at end of file diff --git a/fieldtests/cycle-316-self-description/c316_3_smacross_doc.ops.json b/fieldtests/cycle-316-self-description/c316_3_smacross_doc.ops.json new file mode 100644 index 0000000..0f4321d --- /dev/null +++ b/fieldtests/cycle-316-self-description/c316_3_smacross_doc.ops.json @@ -0,0 +1,13 @@ +[ + {"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": "doc", "text": "fast/slow SMA crossover spread turned into a bounded directional bias"}, + {"op": "expose", "from": "bias.bias", "as": "bias"} +] diff --git a/fieldtests/cycle-316-self-description/c316_4_campaign_empty.json b/fieldtests/cycle-316-self-description/c316_4_campaign_empty.json new file mode 100644 index 0000000..0b6a0e7 --- /dev/null +++ b/fieldtests/cycle-316-self-description/c316_4_campaign_empty.json @@ -0,0 +1,11 @@ +{ + "format_version": 1, + "kind": "campaign", + "name": "smacross-explore", + "description": "", + "seed": 42, + "data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] }, + "strategies": [ { "ref": { "content_id": "088632cb7d6b553bfbfdb3cb4d737aec20f355c555f424483a48692dbf3a150d" }, "axes": { "fast.length": { "kind": "I64", "values": [2, 4] } } } ], + "process": { "ref": { "content_id": "088632cb7d6b553bfbfdb3cb4d737aec20f355c555f424483a48692dbf3a150d" } }, + "presentation": { "persist_taps": ["equity"], "emit": ["family_table"] } +} diff --git a/fieldtests/cycle-316-self-description/c316_4_campaign_good.json b/fieldtests/cycle-316-self-description/c316_4_campaign_good.json new file mode 100644 index 0000000..af91927 --- /dev/null +++ b/fieldtests/cycle-316-self-description/c316_4_campaign_good.json @@ -0,0 +1,11 @@ +{ + "format_version": 1, + "kind": "campaign", + "name": "smacross-explore", + "description": "GER40 SMA-crossover parameter exploration", + "seed": 42, + "data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] }, + "strategies": [ { "ref": { "content_id": "088632cb7d6b553bfbfdb3cb4d737aec20f355c555f424483a48692dbf3a150d" }, "axes": { "fast.length": { "kind": "I64", "values": [2, 4] } } } ], + "process": { "ref": { "content_id": "088632cb7d6b553bfbfdb3cb4d737aec20f355c555f424483a48692dbf3a150d" } }, + "presentation": { "persist_taps": ["equity"], "emit": ["family_table"] } +} diff --git a/fieldtests/cycle-316-self-description/c316_4_campaign_nodesc.json b/fieldtests/cycle-316-self-description/c316_4_campaign_nodesc.json new file mode 100644 index 0000000..3d7d943 --- /dev/null +++ b/fieldtests/cycle-316-self-description/c316_4_campaign_nodesc.json @@ -0,0 +1,11 @@ +{ + "format_version": 1, + "kind": "campaign", + "name": "smacross-explore", + + "seed": 42, + "data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] }, + "strategies": [ { "ref": { "content_id": "088632cb7d6b553bfbfdb3cb4d737aec20f355c555f424483a48692dbf3a150d" }, "axes": { "fast.length": { "kind": "I64", "values": [2, 4] } } } ], + "process": { "ref": { "content_id": "088632cb7d6b553bfbfdb3cb4d737aec20f355c555f424483a48692dbf3a150d" } }, + "presentation": { "persist_taps": ["equity"], "emit": ["family_table"] } +} diff --git a/fieldtests/cycle-316-self-description/c316_4_campaign_restate.json b/fieldtests/cycle-316-self-description/c316_4_campaign_restate.json new file mode 100644 index 0000000..ce146d4 --- /dev/null +++ b/fieldtests/cycle-316-self-description/c316_4_campaign_restate.json @@ -0,0 +1,11 @@ +{ + "format_version": 1, + "kind": "campaign", + "name": "smacross-explore", + "description": "smacross-explore", + "seed": 42, + "data": { "instruments": ["GER40"], "windows": [ { "from_ms": 1725148800000, "to_ms": 1727740800000 } ] }, + "strategies": [ { "ref": { "content_id": "088632cb7d6b553bfbfdb3cb4d737aec20f355c555f424483a48692dbf3a150d" }, "axes": { "fast.length": { "kind": "I64", "values": [2, 4] } } } ], + "process": { "ref": { "content_id": "088632cb7d6b553bfbfdb3cb4d737aec20f355c555f424483a48692dbf3a150d" } }, + "presentation": { "persist_taps": ["equity"], "emit": ["family_table"] } +} diff --git a/fieldtests/cycle-316-self-description/c316_4_process_empty.json b/fieldtests/cycle-316-self-description/c316_4_process_empty.json new file mode 100644 index 0000000..c8bf18c --- /dev/null +++ b/fieldtests/cycle-316-self-description/c316_4_process_empty.json @@ -0,0 +1,7 @@ +{ + "format_version": 1, + "kind": "process", + "name": "explore-only-sweep", + "description": "", + "pipeline": [ { "block": "std::sweep" } ] +} diff --git a/fieldtests/cycle-316-self-description/c316_4_process_good.json b/fieldtests/cycle-316-self-description/c316_4_process_good.json new file mode 100644 index 0000000..e0b0a7b --- /dev/null +++ b/fieldtests/cycle-316-self-description/c316_4_process_good.json @@ -0,0 +1,7 @@ +{ + "format_version": 1, + "kind": "process", + "name": "explore-only-sweep", + "description": "records the full axes family without choosing a winner", + "pipeline": [ { "block": "std::sweep" } ] +} diff --git a/fieldtests/cycle-316-self-description/c316_4_process_restate.json b/fieldtests/cycle-316-self-description/c316_4_process_restate.json new file mode 100644 index 0000000..bd09361 --- /dev/null +++ b/fieldtests/cycle-316-self-description/c316_4_process_restate.json @@ -0,0 +1,7 @@ +{ + "format_version": 1, + "kind": "process", + "name": "explore-only-sweep", + "description": "explore-only-sweep", + "pipeline": [ { "block": "std::sweep" } ] +} diff --git a/fieldtests/cycle-316-self-description/lab316-nodes/.gitignore b/fieldtests/cycle-316-self-description/lab316-nodes/.gitignore new file mode 100644 index 0000000..96ef6c0 --- /dev/null +++ b/fieldtests/cycle-316-self-description/lab316-nodes/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/fieldtests/cycle-316-self-description/lab316-nodes/CLAUDE.md b/fieldtests/cycle-316-self-description/lab316-nodes/CLAUDE.md new file mode 100644 index 0000000..4b7253b --- /dev/null +++ b/fieldtests/cycle-316-self-description/lab316-nodes/CLAUDE.md @@ -0,0 +1,11 @@ +# lab316-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 + `lab316_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. diff --git a/fieldtests/cycle-316-self-description/lab316-nodes/Cargo.toml b/fieldtests/cycle-316-self-description/lab316-nodes/Cargo.toml new file mode 100644 index 0000000..bc07d3f --- /dev/null +++ b/fieldtests/cycle-316-self-description/lab316-nodes/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "lab316-nodes" +version = "0.1.0" +edition = "2024" +publish = false + +[lib] +crate-type = ["cdylib"] + +[dependencies] +aura-core = { path = "/home/brummel/dev/aura/.claude/worktrees/issue-316-self-description/crates/aura-core" } + +# Standalone workspace root: never a member of an enclosing workspace. +[workspace] diff --git a/fieldtests/cycle-316-self-description/lab316-nodes/src/lib.rs b/fieldtests/cycle-316-self-description/lab316-nodes/src/lib.rs new file mode 100644 index 0000000..bc38ed0 --- /dev/null +++ b/fieldtests/cycle-316-self-description/lab316-nodes/src/lib.rs @@ -0,0 +1,75 @@ +//! lab316-nodes — an aura research project: node logic + the exported vocabulary. +//! +//! Every node type this crate provides is registered in `vocabulary()` / +//! `type_ids()` under the `lab316_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( + "lab316_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 }], + 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 { + 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!("lab316_nodes::Scale({})", self.factor) + } +} + +fn vocabulary(type_id: &str) -> Option { + match type_id { + "lab316_nodes::Scale" => Some(Scale::builder()), + _ => None, + } +} + +fn type_ids() -> &'static [&'static str] { + &["lab316_nodes::Scale"] +} + +aura_core::aura_project! { + namespace: "lab316_nodes", + vocabulary: vocabulary, + type_ids: type_ids, +} diff --git a/fieldtests/cycle-316-self-description/lab316/.gitignore b/fieldtests/cycle-316-self-description/lab316/.gitignore new file mode 100644 index 0000000..306cbf0 --- /dev/null +++ b/fieldtests/cycle-316-self-description/lab316/.gitignore @@ -0,0 +1 @@ +/runs diff --git a/fieldtests/cycle-316-self-description/lab316/Aura.toml b/fieldtests/cycle-316-self-description/lab316/Aura.toml new file mode 100644 index 0000000..5f25964 --- /dev/null +++ b/fieldtests/cycle-316-self-description/lab316/Aura.toml @@ -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 = ["../lab316-nodes"] diff --git a/fieldtests/cycle-316-self-description/lab316/CLAUDE.md b/fieldtests/cycle-316-self-description/lab316/CLAUDE.md new file mode 100644 index 0000000..2d2770a --- /dev/null +++ b/fieldtests/cycle-316-self-description/lab316/CLAUDE.md @@ -0,0 +1,14 @@ +# lab316 — 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 run blueprints/signal.json` (the starter is closed — all + params bound; bound values are defaults — any `--axis` may override them + (#246)) +- Sweep: `aura sweep blueprints/signal.json --axis lab316_signal.fast.length=2,4,8` + (`aura sweep --list-axes` lists the open + bound-overridable axes) +- Native nodes: when the project needs its first project-specific node, + `aura nodes new ` scaffolds a node crate beside this project and + attaches it via `[nodes]` in `Aura.toml` (build it with `cargo build`). +- Topology is data (`blueprints/*.json`); results land in `runs/`. diff --git a/fieldtests/cycle-316-self-description/lab316/blueprints/signal.json b/fieldtests/cycle-316-self-description/lab316/blueprints/signal.json new file mode 100644 index 0000000..27c7913 --- /dev/null +++ b/fieldtests/cycle-316-self-description/lab316/blueprints/signal.json @@ -0,0 +1 @@ +{"format_version":1,"blueprint":{"name":"lab316_signal","doc":"fast/slow SMA difference clamped into a directional bias","nodes":[{"primitive":{"type":"SMA","name":"fast","bound":[{"pos":0,"name":"length","kind":"I64","value":{"I64":2}}]}},{"primitive":{"type":"SMA","name":"slow","bound":[{"pos":0,"name":"length","kind":"I64","value":{"I64":4}}]}},{"primitive":{"type":"Sub"}},{"primitive":{"type":"Bias","name":"bias","bound":[{"pos":0,"name":"scale","kind":"F64","value":{"F64":0.5}}]}}],"edges":[{"from":0,"to":2,"slot":0,"from_field":0},{"from":1,"to":2,"slot":1,"from_field":0},{"from":2,"to":3,"slot":0,"from_field":0}],"input_roles":[{"name":"price","targets":[{"node":0,"slot":0},{"node":1,"slot":0}],"source":"F64"}],"output":[{"node":3,"field":0,"name":"bias"}]}} \ No newline at end of file