Process & campaign document vocabularies: parse, validate, introspect, content-address (no executor) #189
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Define the two research-artifact document types from the #188 role-model design pass — the process document (role 5: a named, versionable validation/eval methodology) and the campaign document (role 6b: persisted experiment intent — data windows × strategy references × axes × process reference × data-level presentation) — as closed-vocabulary, typed, serialized data, with parsing, validation, the introspection contract, and content-addressing. No executor in this cycle.
Design basis (all on #188): the issue body (role model, resolved forks 1–4), the addendum comments (introspection contract from day one; P1 control-flow tier: axes / gates / ladders), the fork-triage comment (decided items 1–8), and the resolution comment (user decisions A–C). Key constraints fixed there:
format_versionenvelope; content id through the same hashing primitive blueprints use; documents stored content-addressed beside blueprints in the registry store pattern.aura.Acceptance sketch: an LLM or human can author a process document and a campaign document as text, validate both headlessly with precise refusals, introspect the vocabularies and any partial document's open slots via the CLI, and obtain stable content ids for both — without any Rust compile and without any run being executed.
sweep/mc/walkforward/generalize) are later cycles, gated on the resolution comment's "once it carries" rule.Design reconciliation (spec production, cycle 0106)
Spec: 0106 research-artifact vocabularies. The design basis is #188 (body, both addenda, fork-triage comment, resolution comment); the derived decisions below close the remaining spec-bearing forks. Each is a derived orchestrator decision with its rationale — none is a user decision unless quoted.
aura-research. Derived: it names the domain (the research loop's document layer — both artifact types serve it equally) without privileging one document type and without colliding with the C13 deploy-artifact vocabulary that "artifact" alone would evoke.aura-research. Derived: the serde-free convention exists to keep wire formats out of the sim core (engineOpvs CLIOpDoc, #162 precedent); a document-definition leaf crate IS the wire format's home, so a parallel DTO layer would duplicate every type for no boundary gain.aura-researchhosts the canonical-bytes SHA-256 helper as a library function;aura-cli's existingcontent_iddelegates to it. Derived: the fork-triage comment fixed "same primitive" for all content ids; today that primitive lives in the binary (aura-cli), unreachable by a library crate — hosting it in the new leaf and delegating keeps exactly one implementation without inverting any dependency.aura process …andaura campaign …, each withvalidate <file>andintrospectmirroring the shippedgraph introspectflag idiom (--vocabulary/--block <id>/--unwired <file>/--content-id <file>). Derived: #188 defines role recognizability as "a surface addressed to the role" (role 5 → process verbs, role 6b → campaign verbs), and reusing the one shipped introspection idiom keeps a single learnable contract across all three artifact classes.{metric, comparator, value}triples over the declared metric vocabulary with a closed comparator set; never a string expression. Derived: a string predicate is a mini-DSL hole that fails the ratified Blockly litmus test (a palette cannot type an opaque string), while structured triples are exactly typed slots.processes/<hash>.json,campaigns/<hash>.json) ships this cycle. Derived: the resolution comment fixed "stored content-addressed alongside blueprints (the existing store pattern)", and the referential validation tier is inert without it; the blueprint store is the shipped template.sweep(grid evaluation + selection rule argmax / plateau:mean / plateau:worst, optional deflation annotation),monte_carlo(R-bootstrap: resamples, block length),walk_forward(fold policy + in-sample selection),generalize(cross-instrument worst-case floor); the declared-metric vocabulary is the scalar field names of the shipped metrics/selection types. Derived: the fork-triage comment fixed "wrap what exists — no invented taxonomy"; this is the complete inventory of shipped selection/validation machinery, nothing more.Status: all spec-bearing forks closed; spec production for cycle 0106 proceeds on this basis.
Spec auto-signed (cycle 0106)
Spec 0106 (research-artifact vocabularies: process & campaign documents — parse, two-tier validation, introspection contract, content-addressing; no executor) was signed autonomously: the signature is a grounding-check PASS from a fresh-context reviewer — all eleven load-bearing assumptions about current codebase behaviour ratified by named, currently-green tests (shared content-id primitive + canonical golden, blueprint-store round-trip, exactly-one-of introspect guard, usage-2/runtime-1 exit split, Display-free-fault prose seam, typed Scalar bind cells, RMetrics/RunMetrics field pins, FamilySelection annotation round-trips, SelectionMode↔--select parity, Aura.toml walk-up discovery, blueprint_from_json + param_space). No human signed; the plan proceeds and a reply here vetoes.
Axis representation corrected (user veto, 2026-07-03)
The spec's first draft carried per-value tagged Scalar cells in campaign axes (
"fast": [{"I64": 8}, …]), derived from op-script bind parity. The user vetoed while the plan was being written: "Macht total Sinn, dass für einen klar typisierten Parameter 'fast' jede einzelne Value im JSON eine typisierte Scalar-Zelle benötigt, nicht wahr?! Das sollte man mal reviewen" (2026-07-03) — the kind is a property of the parameter, not of each value.Resolution (spec amended before any implementation): an axis declares its ScalarKind once —
{"kind": "I64", "values": [8, 12, 16]}— with bare JSON values parsed as the declared kind. A mixed-kind axis is thereby unrepresentable rather than merely refused (stronger than the draft, which needed an extra validation rule to forbid mixes), and canonical serialization normalizes value spelling (an F64 axis writes 8 as 8.0), keeping content ids stable across equivalent spellings. The bind-parity rationale was mis-applied: an op-script bind slot holds exactly one value, so there the per-cell tag is the only kind carrier; an axis is a homogeneous list. Binds stay tagged; axes carry the kind once. The referential tier's kind check becomes one comparison per axis (declared kind vs the param's ScalarKind) instead of per cell.