docs(readme, guides, glossary, ledger), bench: the surviving surface everywhere
Slice 8, closing the #319 retirement's prose and bench debt. Bench argv rides exec (fixed_cost single-run probe, campaign surfaces, and the seed helper that still called the retired sweep at runtime — caught by the bench run itself); all five fingerprints unchanged against the committed baselines, confirming record-line parity through the retirement. Live docs (README, authoring guide, project layout, glossary) describe only exec + campaign documents + graph introspect --params; three glossary entries explicitly mark their verb retired. Ledger amendments per the C29 discipline — C25's executor-verb-set re-settled (exec + the --override residue), C14's dual grammar reduced to the one dispatch, C24's document-built runs/families + gated-intake route list (lockstep with the code comment), C12's override clause and identity anchor repointed to the runner-layer hash computation, C18/C22/C27/C01 mention rewrites — superseded sentences moved verbatim to the history sidecars (c25's created). Stale dual-grammar doc comment on is_blueprint_file rewritten. refs #319
This commit is contained in:
+45
-37
@@ -10,7 +10,7 @@ JSON artifact kinds you author headlessly along that arc:
|
||||
through `aura process validate|introspect|register|show`;
|
||||
3. a **campaign document** (role 6b) — experiment intent (instruments ×
|
||||
windows × strategy × axes × process) through `aura campaign
|
||||
validate|introspect|register|show|run|runs`.
|
||||
validate|introspect|register|runs|show`, executed by `aura exec` (#319).
|
||||
|
||||
Each section below is a worked, verified example — every command shown was
|
||||
run against this repo and the output is transcribed, not invented. The *why*
|
||||
@@ -39,9 +39,11 @@ the same shape every node in `aura-std` already follows.
|
||||
scaffolds a **data-only** project (`docs/project-layout.md`, "A project
|
||||
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
|
||||
(bound = default, not fixed); `--list-axes` lists the open knobs and the
|
||||
`signal.json` starter that serves both legs of `exec` (#319) — `aura exec
|
||||
signal.json` uses its bound values as-is, `aura exec signal.json --override
|
||||
fast.length=8` reopens one for that run, and a campaign document's
|
||||
`strategies[].axes` reopens one across a family (bound = default, not
|
||||
fixed); `aura graph introspect --params` 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
|
||||
pattern is actually needed — lives in an attached **node crate**:
|
||||
@@ -240,7 +242,7 @@ are dotted `<identifier>.<port>` on both sides of a wire.
|
||||
| `feed` | `{"op":"feed","role":<str>,"into":[<port>, …]}` | fan a previously-declared role into one or more interior input slots, all-or-nothing (a failing target leaves none of the batch wired). |
|
||||
| `connect` | `{"op":"connect","from":<port>,"to":<port>}` | wire one interior output field to one interior input slot. A `connect` that would close a dataflow cycle is rejected immediately — the only legal feedback path is an explicit delay/state node (domain invariant 5). |
|
||||
| `expose` | `{"op":"expose","from":<port>,"as":<str>}` | promote an interior output field to a boundary output under the alias `as` — a real *alias* (a terminal boundary name, not a referenceable identifier like `add`'s `name`). Together with `tap`, one of the two ops whose `as` key is a terminal name rather than an identifier. |
|
||||
| `tap` | `{"op":"tap","from":<port>,"as":<str>}` | declare a **measurement tap** on an interior output field under the name `as` — the output-side twin of `expose` (a recorded observation point, not a boundary output; a `Composite.taps` entry, C27). A single `aura run` constructs a recorder at each declared tap and persists its per-cycle series as a `ColumnarTrace`; a sweep leaves it inert. Tap names are their own namespace and must be unique (a second `tap` under one name refuses: `duplicate tap name`). |
|
||||
| `tap` | `{"op":"tap","from":<port>,"as":<str>}` | declare a **measurement tap** on an interior output field under the name `as` — the output-side twin of `expose` (a recorded observation point, not a boundary output; a `Composite.taps` entry, C27). A single `aura exec` constructs a recorder at each declared tap and persists its per-cycle series as a `ColumnarTrace`; a campaign member run leaves it inert. Tap names are their own namespace and must be unique (a second `tap` under one name refuses: `duplicate tap name`). |
|
||||
| `gang` | `{"op":"gang","as":"channel_length","into":["channel_hi.length","channel_lo.length"]}` | Fuse two or more sibling params into ONE public knob: the member addresses leave the sweepable param space and `as` replaces them; the bound or swept value fans out to every member at bootstrap. Members must share one scalar kind and stay open (un-bound). |
|
||||
|
||||
Omitting `name` is fine for a single strategy, but it has three live
|
||||
@@ -283,9 +285,10 @@ corpus's own example, verified below; byte-identical to the on-disk
|
||||
|
||||
A `bind` in an `add` op pins that param to a value and removes it from the
|
||||
**open** param space (`--params`): a bound param is a **default** (#246) — a
|
||||
run uses it as-is, while any campaign axis or `aura sweep --axis` naming it
|
||||
re-opens it for that family and binds it per cell. `--list-axes` lists it
|
||||
after the open knobs as `<name>:<KIND> default=<value>`. `bind` is for a
|
||||
plain `exec` uses it as-is, while a campaign axis naming it re-opens it for
|
||||
that family (bound per cell) and `exec`'s own `--override NODE.PARAM=VALUE`
|
||||
(#319) re-opens it for that one execution. `graph introspect --params` lists
|
||||
it after the open knobs as `<name>:<KIND> default=<value>`. `bind` is for a
|
||||
value the strategy carries by default; leave a param unbound, as all three
|
||||
are here, to make binding it mandatory for every sweep.
|
||||
|
||||
@@ -293,7 +296,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 —
|
||||
e.g. `channel_length` — appears in `--list-axes`).
|
||||
e.g. `channel_length` — appears in `graph introspect --params`).
|
||||
|
||||
### Worked example: declaring a measurement tap
|
||||
|
||||
@@ -322,10 +325,12 @@ bias scaling) under the name `spread`:
|
||||
|
||||
The built blueprint carries a `taps` array naming the resolved wire
|
||||
(`{"name":"spread","from":{"node":<sub's index>,"field":0}}` — the name is
|
||||
addressed, the index is resolved *for* you). A single `aura run <blueprint>`
|
||||
addressed, the index is resolved *for* you). A single `aura exec <blueprint>`
|
||||
then constructs a recorder at that point and persists the `spread` series as a
|
||||
`ColumnarTrace` in the run's trace store, chartable by its name. A tap is inert
|
||||
in a sweep (no per-cell recorder) — it is a single-run observation surface.
|
||||
in a campaign member run (no per-cell recorder) — it is a single-run
|
||||
observation surface (or, per campaign, what a nominee's `persist_taps`
|
||||
re-run records, §3).
|
||||
(`sub.value` is tapped here purely to illustrate; any interior output field is
|
||||
a legal tap source, and a producer needs no other consumer to be tapped.)
|
||||
|
||||
@@ -422,29 +427,32 @@ slow.length:I64
|
||||
bias.scale:F64
|
||||
```
|
||||
|
||||
These printed names are the **one** axis namespace (#328): op-script params, a
|
||||
campaign document's `strategies[].axes` keys (§3), and `aura sweep <blueprint>
|
||||
--list-axes` / `--axis` (glossary `sweep`) all speak the same raw
|
||||
`<node>.<param>` form — `--params` and `--list-axes` are line-identical (open
|
||||
params bare, bound params trailing `default=<value>`), and every discovered
|
||||
name is verbatim legal as a document axis key, bound params included (#246's
|
||||
re-open contract):
|
||||
These printed names are the **one** axis namespace (#328): op-script params
|
||||
and a campaign document's `strategies[].axes` keys (§3) speak the same raw
|
||||
`<node>.<param>` form as `graph introspect --params` prints (open params
|
||||
bare, bound params trailing `default=<value>`) — every discovered name is
|
||||
verbatim legal as a document axis key, bound params included (#246's
|
||||
re-open contract), and as the token `exec --override NODE.PARAM=VALUE` (#319)
|
||||
takes on the single-run leg:
|
||||
|
||||
```json
|
||||
"strategies": [ { "ref": { "content_id": "…" },
|
||||
"axes": { "fast.length": { "kind": "I64", "values": [3, 5, 7, 9] },
|
||||
"bias.scale": { "kind": "F64", "values": [0.25, 0.5] } } } ]
|
||||
```
|
||||
|
||||
A single execution reopens the same raw name directly, with no document at all:
|
||||
|
||||
```
|
||||
$ 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
|
||||
$ aura exec smacross.json --override fast.length=5 # single run: raw works
|
||||
```
|
||||
|
||||
The older `<blueprint>.<node>.<param>` 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:
|
||||
what pre-#328 transcripts and the retired `--list-axes` output used to print)
|
||||
is retired from the surface; naming it in a campaign document refuses with a
|
||||
translation pointer to the raw candidate, the one remaining intake seam:
|
||||
|
||||
```
|
||||
$ 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 f5fdf729d0333f0286c19d57143fb7933137f27a6128e72489c508096c7a2240:
|
||||
@@ -704,7 +712,7 @@ campaign document valid (executable): pipeline shape and static guards pass
|
||||
```
|
||||
$ aura campaign register mra_3_campaign_full_v2.json
|
||||
registered campaign 42edebd2159de708009ba21e1ed4aea2cffabc373bf761c5765f79c190b677bd (…/runs/campaigns/42ed…json)
|
||||
$ aura campaign run 42edebd2159de708009ba21e1ed4aea2cffabc373bf761c5765f79c190b677bd
|
||||
$ aura exec 42edebd2159de708009ba21e1ed4aea2cffabc373bf761c5765f79c190b677bd
|
||||
{"family_id":"42edebd2-0-GER40-w0-s0-0","report":{...}}
|
||||
{"family_id":"42edebd2-0-GER40-w0-s0-0-r1","report":{...}}
|
||||
…
|
||||
@@ -730,19 +738,19 @@ regime's family ids and trace dirs carry the `-r1` ordinal suffix (the
|
||||
default/first regime stays unsuffixed), each cell record names its regime,
|
||||
and generalization is keyed per regime — regimes are compared, never pooled.
|
||||
|
||||
`aura campaign run` is register-then-run sugar for a `.json` file, but the
|
||||
`aura exec` (#319) is register-then-run sugar for a `.json` file, but the
|
||||
canonical address is always the content id — running a bare file the first
|
||||
time registers it implicitly. `aura campaign runs` lists stored
|
||||
realizations; `aura campaign runs <id>` dumps the bare stored record(s) (not
|
||||
the `{"campaign_run": …}` emit wrapper above). If `presentation.persist_taps`
|
||||
is non-empty, the run also persists the named taps under
|
||||
`runs/traces/<trace_name>/…`, chartable with `aura chart`. The
|
||||
`sweep`/`walkforward --trace` analog persists every member's taps as a
|
||||
family charted the same way, by the handle the run prints (members keyed
|
||||
`<cell>/<member>`) — also by the `--trace <NAME>` you chose, when that name
|
||||
uniquely names one recorded run (`aura chart <NAME>` resolves it against the
|
||||
stored campaign documents; a name reused across runs refuses rather than
|
||||
guessing which one you mean).
|
||||
is non-empty, the run also persists every member's taps under
|
||||
`runs/traces/<trace_name>/…` — the deterministic `{campaign8}-{run}` handle
|
||||
the `campaign_run` record's `trace_name` field prints, never a user-chosen
|
||||
name — chartable with `aura chart <trace_name>` (members keyed
|
||||
`<cell>/<member>`); `aura chart` also resolves a bare campaign id/name
|
||||
against the stored campaign documents when no literal trace directory
|
||||
matches, refusing rather than guessing when the name is ambiguous across
|
||||
recorded runs.
|
||||
|
||||
Exit codes: a clean run exits 0; a usage error exits 2; a refusal before any
|
||||
cell runs (invalid document, missing project, unresolvable strategy) exits 1;
|
||||
|
||||
Reference in New Issue
Block a user