diff --git a/docs/design/INDEX.md b/docs/design/INDEX.md index 331f243..5048587 100644 --- a/docs/design/INDEX.md +++ b/docs/design/INDEX.md @@ -1841,6 +1841,35 @@ sequencing-coupled to the **project-as-crate authoring layer** (`aura new` / `Aura.toml` / `cdylib` loading, C16/C17) and the **composable-orchestration** thread (#109): topology-as-data is the substrate both stand on. +**Op-script grammar (`aura graph build`, the #157 wire surface).** The construction +op-script is a JSON **array of ops**, each object internally tagged by `"op"`, +replayed in order; nodes are referenced **by identifier**, ports as dotted +`.`. The six verbs: +- `source` — `{"op":"source","role":,"kind":}` — declare a root + source role producing a base column of `kind`. +- `input` — `{"op":"input","role":}` — declare a root input role (kind inferred + from the slots it feeds). +- `add` — `{"op":"add","type":,"name":?,"bind":{:}?}` — + add a node of compiled-in type identity `type`; **`name` is its identifier** + (mirrors the builder's `.named(...)`; defaults to the lowercased type label, so + two unnamed nodes of one type collide); `bind` sets params. +- `feed` — `{"op":"feed","role":,"into":[,…]}` — fan a root role into + interior input slots. +- `connect` — `{"op":"connect","from":,"to":}` — wire an interior output + field to an input slot; a `connect` closing a cycle is rejected eagerly + (invariant 5). +- `expose` — `{"op":"expose","from":,"as":}` — promote an interior output + field to a boundary output, aliased by `as` — **the only verb that keeps `as`** + (a real alias, not a naming; contrast `add`'s `name`). + +Value forms are the #155 representations: a `Scalar` bind value is the typed tag form +`{"I64":2}` / `{"F64":0.5}` / `{"Bool":true}` / `{"Timestamp":}`, and `kind` is +the capitalized `ScalarKind` (`"F64"`). Worked example: +`fieldtests/cycle-0088-construction-op-script/c0088_1_sma_crossover.json` +(an SMA-crossover bias). The surface is introspectable build-free: +`aura graph introspect --vocabulary | --node | --unwired`. (Surfacing this same +grammar in `aura graph build --help` rides with the CLI-discoverability work, #159.) + --- ## Open architectural threads not yet resolved diff --git a/fieldtests/cycle-0088-construction-op-script/FINDINGS.md b/fieldtests/cycle-0088-construction-op-script/FINDINGS.md index 068b437..c44da82 100644 --- a/fieldtests/cycle-0088-construction-op-script/FINDINGS.md +++ b/fieldtests/cycle-0088-construction-op-script/FINDINGS.md @@ -3,6 +3,14 @@ **Status:** Triaged 2026-06-29 — filed to the forward queue (see Triage outcome) **Author:** fieldtester (dispatched by fieldtest skill); triaged by orchestrator +> **Corpus refreshed 2026-06-30 (#163)** to replay against the current binary. +> Two drifts had accumulated since this run recorded the fixtures: `add`'s +> naming key was renamed `as` -> `name` (commit `3c4b667`; `expose` keeps `as`), +> and the dataflow-cycle bug below was fixed (`1652042`, closes #161). The `.json` +> inputs now use `name` for `add`; `c0088_3m_two_cycle` is a rejection fixture +> (`c0088_3m.err` carries the cycle-rejection message; the gap-era cyclic-blueprint +> golden was removed). The findings below are preserved as written at fieldtest time. + ## Scope Cycle 0088 shipped the **construction op-script service** (#157, C24): two CLI subcommands over a declarative JSON op-list. `aura graph build` reads an op-list diff --git a/fieldtests/cycle-0088-construction-op-script/c0088_1_sma_crossover.json b/fieldtests/cycle-0088-construction-op-script/c0088_1_sma_crossover.json index 6112d38..53e7cac 100644 --- a/fieldtests/cycle-0088-construction-op-script/c0088_1_sma_crossover.json +++ b/fieldtests/cycle-0088-construction-op-script/c0088_1_sma_crossover.json @@ -1,12 +1,12 @@ [ {"op": "source", "role": "price", "kind": "F64"}, - {"op": "add", "type": "SMA", "as": "fast", "bind": {"length": {"I64": 2}}}, - {"op": "add", "type": "SMA", "as": "slow", "bind": {"length": {"I64": 4}}}, + {"op": "add", "type": "SMA", "name": "fast", "bind": {"length": {"I64": 2}}}, + {"op": "add", "type": "SMA", "name": "slow", "bind": {"length": {"I64": 4}}}, {"op": "feed", "role": "price", "into": ["fast.series", "slow.series"]}, - {"op": "add", "type": "Sub", "as": "sub"}, + {"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", "as": "bias"}, + {"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-0088-construction-op-script/c0088_2_completed.json b/fieldtests/cycle-0088-construction-op-script/c0088_2_completed.json index 15edb0b..c05d17a 100644 --- a/fieldtests/cycle-0088-construction-op-script/c0088_2_completed.json +++ b/fieldtests/cycle-0088-construction-op-script/c0088_2_completed.json @@ -1,12 +1,12 @@ [ {"op": "source", "role": "price", "kind": "F64"}, - {"op": "add", "type": "SMA", "as": "fast", "bind": {"length": {"I64": 3}}}, - {"op": "add", "type": "SMA", "as": "slow", "bind": {"length": {"I64": 8}}}, + {"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", "as": "sub"}, + {"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", "as": "bias"}, + {"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-0088-construction-op-script/c0088_2_partial.json b/fieldtests/cycle-0088-construction-op-script/c0088_2_partial.json index 25248d8..04c7019 100644 --- a/fieldtests/cycle-0088-construction-op-script/c0088_2_partial.json +++ b/fieldtests/cycle-0088-construction-op-script/c0088_2_partial.json @@ -1,9 +1,9 @@ [ {"op": "source", "role": "price", "kind": "F64"}, - {"op": "add", "type": "SMA", "as": "fast", "bind": {"length": {"I64": 3}}}, - {"op": "add", "type": "SMA", "as": "slow", "bind": {"length": {"I64": 8}}}, + {"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", "as": "sub"}, + {"op": "add", "type": "Sub", "name": "sub"}, {"op": "connect", "from": "fast.value", "to": "sub.lhs"}, - {"op": "add", "type": "Bias", "as": "bias"} + {"op": "add", "type": "Bias", "name": "bias"} ] diff --git a/fieldtests/cycle-0088-construction-op-script/c0088_3a_bad_type.json b/fieldtests/cycle-0088-construction-op-script/c0088_3a_bad_type.json index 854dc74..95accdb 100644 --- a/fieldtests/cycle-0088-construction-op-script/c0088_3a_bad_type.json +++ b/fieldtests/cycle-0088-construction-op-script/c0088_3a_bad_type.json @@ -1,6 +1,6 @@ [ {"op": "source", "role": "price", "kind": "F64"}, - {"op": "add", "type": "Smaa", "as": "fast", "bind": {"length": {"I64": 2}}}, + {"op": "add", "type": "Smaa", "name": "fast", "bind": {"length": {"I64": 2}}}, {"op": "feed", "role": "price", "into": ["fast.series"]}, {"op": "expose", "from": "fast.value", "as": "out"} ] diff --git a/fieldtests/cycle-0088-construction-op-script/c0088_3b_wrong_kind.json b/fieldtests/cycle-0088-construction-op-script/c0088_3b_wrong_kind.json index ce06f27..c5db09e 100644 --- a/fieldtests/cycle-0088-construction-op-script/c0088_3b_wrong_kind.json +++ b/fieldtests/cycle-0088-construction-op-script/c0088_3b_wrong_kind.json @@ -1,7 +1,7 @@ [ {"op": "source", "role": "price", "kind": "F64"}, - {"op": "add", "type": "Gt", "as": "g"}, - {"op": "add", "type": "SMA", "as": "fast", "bind": {"length": {"I64": 2}}}, + {"op": "add", "type": "Gt", "name": "g"}, + {"op": "add", "type": "SMA", "name": "fast", "bind": {"length": {"I64": 2}}}, {"op": "feed", "role": "price", "into": ["g.a", "g.b"]}, {"op": "connect", "from": "g.value", "to": "fast.series"}, {"op": "expose", "from": "fast.value", "as": "out"} diff --git a/fieldtests/cycle-0088-construction-op-script/c0088_3c_wrong_port.json b/fieldtests/cycle-0088-construction-op-script/c0088_3c_wrong_port.json index f0143f4..d563e0d 100644 --- a/fieldtests/cycle-0088-construction-op-script/c0088_3c_wrong_port.json +++ b/fieldtests/cycle-0088-construction-op-script/c0088_3c_wrong_port.json @@ -1,7 +1,7 @@ [ {"op": "source", "role": "price", "kind": "F64"}, - {"op": "add", "type": "SMA", "as": "fast", "bind": {"length": {"I64": 2}}}, - {"op": "add", "type": "Sub", "as": "sub"}, + {"op": "add", "type": "SMA", "name": "fast", "bind": {"length": {"I64": 2}}}, + {"op": "add", "type": "Sub", "name": "sub"}, {"op": "feed", "role": "price", "into": ["fast.series"]}, {"op": "connect", "from": "fast.output", "to": "sub.lhs"}, {"op": "expose", "from": "sub.value", "as": "out"} diff --git a/fieldtests/cycle-0088-construction-op-script/c0088_3d_unknown_node_id.json b/fieldtests/cycle-0088-construction-op-script/c0088_3d_unknown_node_id.json index 94f30f7..4f704f9 100644 --- a/fieldtests/cycle-0088-construction-op-script/c0088_3d_unknown_node_id.json +++ b/fieldtests/cycle-0088-construction-op-script/c0088_3d_unknown_node_id.json @@ -1,7 +1,7 @@ [ {"op": "source", "role": "price", "kind": "F64"}, - {"op": "add", "type": "SMA", "as": "fast", "bind": {"length": {"I64": 2}}}, - {"op": "add", "type": "Sub", "as": "sub"}, + {"op": "add", "type": "SMA", "name": "fast", "bind": {"length": {"I64": 2}}}, + {"op": "add", "type": "Sub", "name": "sub"}, {"op": "feed", "role": "price", "into": ["fast.series"]}, {"op": "connect", "from": "fst.value", "to": "sub.lhs"}, {"op": "expose", "from": "sub.value", "as": "out"} diff --git a/fieldtests/cycle-0088-construction-op-script/c0088_3e_double_wired.json b/fieldtests/cycle-0088-construction-op-script/c0088_3e_double_wired.json index a87022d..b59ccdb 100644 --- a/fieldtests/cycle-0088-construction-op-script/c0088_3e_double_wired.json +++ b/fieldtests/cycle-0088-construction-op-script/c0088_3e_double_wired.json @@ -1,8 +1,8 @@ [ {"op": "source", "role": "price", "kind": "F64"}, - {"op": "add", "type": "SMA", "as": "fast", "bind": {"length": {"I64": 2}}}, - {"op": "add", "type": "SMA", "as": "slow", "bind": {"length": {"I64": 4}}}, - {"op": "add", "type": "Sub", "as": "sub"}, + {"op": "add", "type": "SMA", "name": "fast", "bind": {"length": {"I64": 2}}}, + {"op": "add", "type": "SMA", "name": "slow", "bind": {"length": {"I64": 4}}}, + {"op": "add", "type": "Sub", "name": "sub"}, {"op": "feed", "role": "price", "into": ["fast.series", "slow.series"]}, {"op": "connect", "from": "fast.value", "to": "sub.lhs"}, {"op": "connect", "from": "slow.value", "to": "sub.lhs"}, diff --git a/fieldtests/cycle-0088-construction-op-script/c0088_3f_dup_name.json b/fieldtests/cycle-0088-construction-op-script/c0088_3f_dup_name.json index 1cf1ac9..6e17338 100644 --- a/fieldtests/cycle-0088-construction-op-script/c0088_3f_dup_name.json +++ b/fieldtests/cycle-0088-construction-op-script/c0088_3f_dup_name.json @@ -1,7 +1,7 @@ [ {"op": "source", "role": "price", "kind": "F64"}, - {"op": "add", "type": "SMA", "as": "fast", "bind": {"length": {"I64": 2}}}, - {"op": "add", "type": "SMA", "as": "fast", "bind": {"length": {"I64": 4}}}, + {"op": "add", "type": "SMA", "name": "fast", "bind": {"length": {"I64": 2}}}, + {"op": "add", "type": "SMA", "name": "fast", "bind": {"length": {"I64": 4}}}, {"op": "feed", "role": "price", "into": ["fast.series"]}, {"op": "expose", "from": "fast.value", "as": "out"} ] diff --git a/fieldtests/cycle-0088-construction-op-script/c0088_3g_bad_bind_kind.json b/fieldtests/cycle-0088-construction-op-script/c0088_3g_bad_bind_kind.json index 4cbe630..71e9ec4 100644 --- a/fieldtests/cycle-0088-construction-op-script/c0088_3g_bad_bind_kind.json +++ b/fieldtests/cycle-0088-construction-op-script/c0088_3g_bad_bind_kind.json @@ -1,6 +1,6 @@ [ {"op": "source", "role": "price", "kind": "F64"}, - {"op": "add", "type": "SMA", "as": "fast", "bind": {"length": {"F64": 2.0}}}, + {"op": "add", "type": "SMA", "name": "fast", "bind": {"length": {"F64": 2.0}}}, {"op": "feed", "role": "price", "into": ["fast.series"]}, {"op": "expose", "from": "fast.value", "as": "out"} ] diff --git a/fieldtests/cycle-0088-construction-op-script/c0088_3h_bad_expose.json b/fieldtests/cycle-0088-construction-op-script/c0088_3h_bad_expose.json index 7d5a3f6..bb43751 100644 --- a/fieldtests/cycle-0088-construction-op-script/c0088_3h_bad_expose.json +++ b/fieldtests/cycle-0088-construction-op-script/c0088_3h_bad_expose.json @@ -1,6 +1,6 @@ [ {"op": "source", "role": "price", "kind": "F64"}, - {"op": "add", "type": "SMA", "as": "fast", "bind": {"length": {"I64": 2}}}, + {"op": "add", "type": "SMA", "name": "fast", "bind": {"length": {"I64": 2}}}, {"op": "feed", "role": "price", "into": ["fast.series"]}, {"op": "expose", "from": "fast.zzz", "as": "out"} ] diff --git a/fieldtests/cycle-0088-construction-op-script/c0088_3i_unfed_role.json b/fieldtests/cycle-0088-construction-op-script/c0088_3i_unfed_role.json index 7d2feac..1e7c4cd 100644 --- a/fieldtests/cycle-0088-construction-op-script/c0088_3i_unfed_role.json +++ b/fieldtests/cycle-0088-construction-op-script/c0088_3i_unfed_role.json @@ -1,6 +1,6 @@ [ {"op": "source", "role": "price", "kind": "F64"}, - {"op": "add", "type": "SMA", "as": "fast", "bind": {"length": {"I64": 2}}}, + {"op": "add", "type": "SMA", "name": "fast", "bind": {"length": {"I64": 2}}}, {"op": "connect", "from": "fast.value", "to": "fast.series"}, {"op": "expose", "from": "fast.value", "as": "out"} ] diff --git a/fieldtests/cycle-0088-construction-op-script/c0088_3j_unknown_role.json b/fieldtests/cycle-0088-construction-op-script/c0088_3j_unknown_role.json index 9d07175..21132ee 100644 --- a/fieldtests/cycle-0088-construction-op-script/c0088_3j_unknown_role.json +++ b/fieldtests/cycle-0088-construction-op-script/c0088_3j_unknown_role.json @@ -1,6 +1,6 @@ [ {"op": "source", "role": "price", "kind": "F64"}, - {"op": "add", "type": "SMA", "as": "fast", "bind": {"length": {"I64": 2}}}, + {"op": "add", "type": "SMA", "name": "fast", "bind": {"length": {"I64": 2}}}, {"op": "feed", "role": "pryce", "into": ["fast.series"]}, {"op": "expose", "from": "fast.value", "as": "out"} ] diff --git a/fieldtests/cycle-0088-construction-op-script/c0088_3k_feed_bad_port.json b/fieldtests/cycle-0088-construction-op-script/c0088_3k_feed_bad_port.json index d7adfda..d7c9e56 100644 --- a/fieldtests/cycle-0088-construction-op-script/c0088_3k_feed_bad_port.json +++ b/fieldtests/cycle-0088-construction-op-script/c0088_3k_feed_bad_port.json @@ -1,6 +1,6 @@ [ {"op": "source", "role": "price", "kind": "F64"}, - {"op": "add", "type": "SMA", "as": "fast", "bind": {"length": {"I64": 2}}}, + {"op": "add", "type": "SMA", "name": "fast", "bind": {"length": {"I64": 2}}}, {"op": "feed", "role": "price", "into": ["fast.serie"]}, {"op": "expose", "from": "fast.value", "as": "out"} ] diff --git a/fieldtests/cycle-0088-construction-op-script/c0088_3l_no_expose.json b/fieldtests/cycle-0088-construction-op-script/c0088_3l_no_expose.json index 809b65e..66b2b89 100644 --- a/fieldtests/cycle-0088-construction-op-script/c0088_3l_no_expose.json +++ b/fieldtests/cycle-0088-construction-op-script/c0088_3l_no_expose.json @@ -1,5 +1,5 @@ [ {"op": "source", "role": "price", "kind": "F64"}, - {"op": "add", "type": "SMA", "as": "fast", "bind": {"length": {"I64": 2}}}, + {"op": "add", "type": "SMA", "name": "fast", "bind": {"length": {"I64": 2}}}, {"op": "feed", "role": "price", "into": ["fast.series"]} ] diff --git a/fieldtests/cycle-0088-construction-op-script/c0088_3m.err b/fieldtests/cycle-0088-construction-op-script/c0088_3m.err index e69de29..2b976fc 100644 --- a/fieldtests/cycle-0088-construction-op-script/c0088_3m.err +++ b/fieldtests/cycle-0088-construction-op-script/c0088_3m.err @@ -0,0 +1 @@ +aura: op 5 (connect): connecting b.value -> a.lhs would close a cycle diff --git a/fieldtests/cycle-0088-construction-op-script/c0088_3m_blueprint.out.json b/fieldtests/cycle-0088-construction-op-script/c0088_3m_blueprint.out.json deleted file mode 100644 index c188f16..0000000 --- a/fieldtests/cycle-0088-construction-op-script/c0088_3m_blueprint.out.json +++ /dev/null @@ -1 +0,0 @@ -{"format_version":1,"blueprint":{"name":"graph","nodes":[{"primitive":{"type":"Sub","name":"a"}},{"primitive":{"type":"Sub","name":"b"}}],"edges":[{"from":0,"to":1,"slot":0,"from_field":0},{"from":1,"to":0,"slot":0,"from_field":0}],"input_roles":[{"name":"price","targets":[{"node":0,"slot":1},{"node":1,"slot":1}],"source":"F64"}],"output":[{"node":0,"field":0,"name":"out"}]}} diff --git a/fieldtests/cycle-0088-construction-op-script/c0088_3m_two_cycle.json b/fieldtests/cycle-0088-construction-op-script/c0088_3m_two_cycle.json index b833484..5bb3c1c 100644 --- a/fieldtests/cycle-0088-construction-op-script/c0088_3m_two_cycle.json +++ b/fieldtests/cycle-0088-construction-op-script/c0088_3m_two_cycle.json @@ -1,7 +1,7 @@ [ {"op": "source", "role": "price", "kind": "F64"}, - {"op": "add", "type": "Sub", "as": "a"}, - {"op": "add", "type": "Sub", "as": "b"}, + {"op": "add", "type": "Sub", "name": "a"}, + {"op": "add", "type": "Sub", "name": "b"}, {"op": "feed", "role": "price", "into": ["a.rhs", "b.rhs"]}, {"op": "connect", "from": "a.value", "to": "b.lhs"}, {"op": "connect", "from": "b.value", "to": "a.lhs"}, diff --git a/fieldtests/cycle-0088-construction-op-script/c0088_3n_naive_bind.json b/fieldtests/cycle-0088-construction-op-script/c0088_3n_naive_bind.json index f5086a9..7b9b7e9 100644 --- a/fieldtests/cycle-0088-construction-op-script/c0088_3n_naive_bind.json +++ b/fieldtests/cycle-0088-construction-op-script/c0088_3n_naive_bind.json @@ -1,6 +1,6 @@ [ {"op": "source", "role": "price", "kind": "F64"}, - {"op": "add", "type": "SMA", "as": "fast", "bind": {"length": 2}}, + {"op": "add", "type": "SMA", "name": "fast", "bind": {"length": 2}}, {"op": "feed", "role": "price", "into": ["fast.series"]}, {"op": "expose", "from": "fast.value", "as": "out"} ] diff --git a/fieldtests/cycle-0088-construction-op-script/c0088_3o_lc_kind.json b/fieldtests/cycle-0088-construction-op-script/c0088_3o_lc_kind.json index 4047255..9cc21e8 100644 --- a/fieldtests/cycle-0088-construction-op-script/c0088_3o_lc_kind.json +++ b/fieldtests/cycle-0088-construction-op-script/c0088_3o_lc_kind.json @@ -1,6 +1,6 @@ [ {"op": "source", "role": "price", "kind": "f64"}, - {"op": "add", "type": "SMA", "as": "fast", "bind": {"length": {"I64": 2}}}, + {"op": "add", "type": "SMA", "name": "fast", "bind": {"length": {"I64": 2}}}, {"op": "feed", "role": "price", "into": ["fast.series"]}, {"op": "expose", "from": "fast.value", "as": "out"} ]