diff --git a/README.md b/README.md index 014ca7d..1834a7e 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Invoke it as `aura …` (examples below use the plain name). - **Family** — the set of runs one verb produces over a blueprint (a sweep grid, a Monte-Carlo seed set, a walk-forward window sequence). Families are persisted in a content-addressed store and can be listed, ranked, and reproduced. -- **Axis** — one named, sweepable knob of a blueprint (e.g. `graph.fast.length`), +- **Axis** — one named, sweepable knob of a blueprint (e.g. `fast.length`), bound with a comma-separated value list. A **gang** fuses several sibling knobs into one axis (one value drives all members). diff --git a/docs/authoring-guide.md b/docs/authoring-guide.md index 82975b7..814ad68 100644 --- a/docs/authoring-guide.md +++ b/docs/authoring-guide.md @@ -40,7 +40,7 @@ the same shape every node in `aura-std` already follows. repo (two tiers)") — a strategy over the std vocabulary is a blueprint/campaign document, not Rust: the scaffold ships **one** closed `signal.json` starter that serves both verbs — `aura run` uses its bound - values as-is, `aura sweep --axis .fast.length=2,4,8` overrides them + values as-is, `aura sweep --axis fast.length=2,4,8` overrides them (bound = default, not fixed); `--list-axes` lists the open knobs and the bound defaults alike, so every override target is discoverable. - **A project-specific *native* node type** — the moment §0's three-part @@ -284,7 +284,7 @@ A param therefore has three states: **open** (an axis every sweep MUST bind), **bound** (a default any axis MAY override, #246), and **ganged** (open, but fused with its siblings under ONE public knob declared by a `gang` op; the member addresses are unbindable and only the gang's own single-segment name — -wrapped like any knob, e.g. `graph.channel_length` — appears in `--list-axes`). +e.g. `channel_length` — appears in `--list-axes`). ### Worked example: declaring a measurement tap @@ -413,23 +413,38 @@ slow.length:I64 bias.scale:F64 ``` -These printed names are the **raw param-space namespace**: op-script params -and a campaign document's `strategies[].axes` keys (§3) share this one raw -form. There is a third, *wrapped* surface: the dissolved `aura sweep - --axis` CLI (glossary `sweep`) accepts only the names `aura -sweep --list-axes` prints — the raw name prefixed with the -root-composite instance name, `graph.` — never the raw form; the -campaign document the sweep sugar generates still stores the raw form -(#210): +These printed names are the **one** axis namespace (#328): op-script params, a +campaign document's `strategies[].axes` keys (§3), and `aura sweep +--list-axes` / `--axis` (glossary `sweep`) all speak the same raw +`.` form — `--params` and `--list-axes` are line-identical (open +params bare, bound params trailing `default=`), and every discovered +name is verbatim legal as a document axis key, bound params included (#246's +re-open contract): ``` -raw (--params, campaign axes): fast.length -wrapped (--list-axes, --axis): graph.fast.length +$ aura sweep smacross.json --axis fast.length=3:9:2 # synthetic: raw works +$ aura sweep smacross.json --axis bias.scale=0.25,0.5 --real ... # real: raw works +``` + +The older `..` wrapped form (e.g. `graph.fast.length`, +what pre-#328 transcripts and `--list-axes` output used to print) is retired +from the surface; naming it refuses with a translation pointer to the raw +candidate, on both intake seams: + +``` +$ aura sweep smacross.json --axis graph.fast.length=... +aura: axis "graph.fast.length": axis names are raw node.param paths — +use "fast.length" (the wrapped --list-axes form was retired, #328) + +$ aura campaign validate wrapped.json # a document quoting an old transcript +aura: campaign references do not resolve: + strategy 9f3a: axis "graph.fast.length" is not in the param space; axis + names are raw node.param paths — did you mean "fast.length"? ``` A ganged knob's raw address has one path segment less than a member address would — it sits at the composite's own level, like a role name (e.g. -`channel_length`, not `channel_hi.length`) — and wraps identically (`graph.channel_length`). +`channel_length`, not `channel_hi.length`). `--content-id`, `--identity-id`, `--params`, and `graph register` all accept **either** shape: the raw op-script array or an already-built `#155` diff --git a/docs/design/contracts/c18-registry.md b/docs/design/contracts/c18-registry.md index 8113274..dcd2052 100644 --- a/docs/design/contracts/c18-registry.md +++ b/docs/design/contracts/c18-registry.md @@ -133,6 +133,18 @@ show ` prints a registered document's canonical bytes (#300), so the generate → retrieve → hand-extend → re-register loop needs no direct store filesystem access. +**The bound-override coincidence (#246, ratified #328).** A campaign axis naming a +**bound** param of the referenced blueprint is deliberately accepted alongside one +naming an open param: `validate_campaign_refs` checks each axis's name against +`param_space()` **OR** `bound_param_space()` — the bound value stands as the +axis's default, and the axis's own values re-open it for that campaign. There is +no schema flag distinguishing the two cases (no `open`/`bound` marker on the axis +entry); name coincidence against one of the two namespaces IS the mechanism, and +the referenced blueprint is the single source of truth for which namespace a name +falls in. Pinned by +`referential_tier_accepts_a_kind_correct_axis_over_a_bound_param` +(`aura-registry/src/lib.rs`). + **The campaign executor.** `aura campaign run ` executes a campaign (a file is register-then-run sugar; the content id is canonical): a zero-fault referential gate, then the process pipeline. The executable shape is diff --git a/docs/design/contracts/c24-blueprint-data.md b/docs/design/contracts/c24-blueprint-data.md index 860e261..41d24fe 100644 --- a/docs/design/contracts/c24-blueprint-data.md +++ b/docs/design/contracts/c24-blueprint-data.md @@ -128,9 +128,14 @@ there is no default; pin a knob you do not want to vary with a single-value axis single `blueprint_axis_probe` (`aura-runner`) single-sources the wrapped probe for the sweep terminal, the MC closed-check, and the listing, so **listed == swept by construction** (and stays so across the harness retirement — the listing tracks -whatever the sweep actually resolves). The names are prefixed by the current wrapping -(`sma_signal.fast.length`, the nested-composite prefix), which is why discovery lives -on the sweep verb (it owns the wrapping), not `graph introspect`. `--trace` on +whatever the sweep actually resolves). One raw namespace, `.` (a splice +path keeps its interior path, e.g. `anchor.sess.period_minutes`), is the only +user-facing axis name (#328): `graph introspect --params` and `--list-axes` are +line-identical (open params bare, bound params with `default=`) and both print +exactly what `--axis` binds, on both sweep routes. The wrapped +`..` form the probe still resolves against internally is +retired from the surface, with a translation refusal naming the raw candidate on +both intake seams (`--axis` and `campaign validate`). `--trace` on `sweep` / `walkforward` writes per-member traces on the real-data campaign path (depth-2 fan-out, chartable by the printed family handle, #224); the synthetic path still refuses (`run` / `mc` refuse `--trace` outright). The live trace-writer is the diff --git a/docs/glossary.md b/docs/glossary.md index 3abe727..768593a 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -331,7 +331,7 @@ The harness's structural parameterization — which strategy, instrument(s), bro ### sweep **Avoid:** param-sweep, parameter sweep -An orchestration axis varying tuning params (grid or random) within a fixed structure. The inner, param-tuning loop, distinct from the structural experiment matrix. On a loaded blueprint every open knob (`--list-axes`) is **required** — a subset is refused with the missing knob named; pin an unwanted knob with a single-value axis (`--axis name=`), there is no default. `aura sweep --axis` takes the `--list-axes`-printed, root-composite-wrapped name (e.g. `graph.fast.length`) — not the raw `param_space` name (`fast.length`) that `graph introspect --params` and a campaign document's axes use; the CLI strips exactly one leading wrapper segment (#210). The `aura sweep` CLI verb is now thin sugar over the `campaign document` path — its blueprint form (` --real`) translates to a generated, content-addressed campaign run through the one executor (#210); the built-in `--strategy` sweep surface was retired by #159 (its hard-wired harnesses removed) — sweep now runs from a blueprint + `--axis`, and a retired `--strategy` token falls to the generic usage error. A ganged pair contributes ONE axis. +An orchestration axis varying tuning params (grid or random) within a fixed structure. The inner, param-tuning loop, distinct from the structural experiment matrix. On a loaded blueprint every open knob (`--list-axes`) is **required** — a subset is refused with the missing knob named; pin an unwanted knob with a single-value axis (`--axis name=`), there is no default. One raw namespace, `.` (a splice path keeps its interior path), is the only axis name (#328): `graph introspect --params` and `aura sweep --list-axes` are line-identical (open params bare, bound params with `default=`), and `--axis` accepts exactly that raw form on both sweep routes — the older `..` wrapped form (e.g. `graph.fast.length`) is retired from the surface; naming it on `--axis` refuses (`axis names are raw node.param paths — use "fast.length" …`), and quoting it in a campaign document gets a did-you-mean toward the raw candidate. The `aura sweep` CLI verb is now thin sugar over the `campaign document` path — its blueprint form (` --real`) translates to a generated, content-addressed campaign run through the one executor (#210); the built-in `--strategy` sweep surface was retired by #159 (its hard-wired harnesses removed) — sweep now runs from a blueprint + `--axis`, and a retired `--strategy` token falls to the generic usage error. A ganged pair contributes ONE axis. ### tap **Avoid:** probe, monitor, scope (for the observation slot — "probe" is taken by the sweep-terminal `blueprint_axis_probe` sense; the #77 `Recorder`→`Probe` rename was retired, 2026-07-21) @@ -347,7 +347,7 @@ The `content id` of a run's signal blueprint in its run-record role: stamped int ### use (op) **Avoid:** — -The construction op that splices a **registered** blueprint into the building graph as a nested `composite` under a chosen instance name (`{"op":"use","ref":{"content_id"|"name":…},"name":…,"bind":{…}}`, #317): the reference — a content id, a unique content-id prefix, or a `blueprint label` — resolves CLI-side, before the engine ever sees it; the fetched composite is C29-gated, spliced, and its resolution echoed on stderr (`aura: note:`, the existing benign marker). The emitted blueprint carries the splice inline as an ordinary nested composite — no reference or registry dependency survives into the artifact. An instance's open input roles become its `.` in-ports, its output boundary fields its `.` out-fields — the existing nested-composite param-prefix discipline extends unchanged (`graph...` on `sweep --list-axes`). Pairs with the `input` op: a pattern meant to be `use`d declares its formal parameters as open `input` roles, left unbound at `finish()` (#317's open-pattern amendment) — only running it standalone requires them bound. +The construction op that splices a **registered** blueprint into the building graph as a nested `composite` under a chosen instance name (`{"op":"use","ref":{"content_id"|"name":…},"name":…,"bind":{…}}`, #317): the reference — a content id, a unique content-id prefix, or a `blueprint label` — resolves CLI-side, before the engine ever sees it; the fetched composite is C29-gated, spliced, and its resolution echoed on stderr (`aura: note:`, the existing benign marker). The emitted blueprint carries the splice inline as an ordinary nested composite — no reference or registry dependency survives into the artifact. An instance's open input roles become its `.` in-ports, its output boundary fields its `.` out-fields — the existing nested-composite param-prefix discipline extends unchanged (`..`, the raw axis form since #328). Pairs with the `input` op: a pattern meant to be `use`d declares its formal parameters as open `input` roles, left unbound at `finish()` (#317's open-pattern amendment) — only running it standalone requires them bound. ### veto **Avoid:** risk-manager