Role-model design pass: nine user roles, two missing artifact types (process, campaign), text-first invariant #188
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?
Design record (in-context discussion, 2026-07-02/03)
This issue anchors the role-model design pass. The framing below was settled in an in-context discussion (user + orchestrator) right after the "Project environment" milestone reached its close gate (#180); this records the ratified parts and the resolved forks, and seeds the artifact-vocabulary design pass that must follow. It refines #109 (the meta-level thread) and gives #72/#182/#183 their conceptual home.
The role model (ratified)
The design lacks an explicit user-role framing (user, 2026-07-02: "im Gesamtdesign fehlt das Framing für die verschiedenen Usergruppen" — with the game-engine analogy: system programmers, toolchain devs, asset creators, game/level designers, players). Roles are cut by artifact + surface + iteration cost, not by org chart. One trader — or an LLM actor, which is the point of the whole authoring design — must be able to fill every role; the separation separates surfaces with different iteration costs and failure modes, not people. Switching roles should be a visible act.
The 6a/6b split is deliberate, not taxonomy polish: it follows invariant 12's tier boundary (node/harness vs World), the two halves speak different visual idioms (dataflow boxes-and-wires vs sequential pipeline blocks; user, 2026-07-03: "Der Datenfluss (die Blueprints) und das Experimentieren damit (Blöcke) sind zwei verschiedene Idiome"), and the interface between them is the id machinery: a campaign references strategies as opaque handles (content id = byte-exact, identity id = topological). Param gradient: 6a defines topology + open params, 6b spans spaces over them (axes/windows), 7 moves inside those spaces live.
Diagnosis (ratified)
User, 2026-07-03: "Einige der acht Rollen sind im Moment nicht ansatzweise erkennbar. Auch wenn sie technisch bereits angelegt sind. Und 5/6 sind technisch im Moment schlicht falsch angelegt."
A role is recognizable when four things exist: a named artifact type it owns; a surface addressed to it (CLI verb family, docs chapter); an entry path; its invariants enforced at its boundary. Applied:
aura-analysiscode — there is no nameable, versionable, referenceable object "our validation process". A campaign evaporates into shell history: the registry records results, but the intent (symbols x strategies x process x presentation) is never persisted — which is also the missing half of role 8's audit story (we can prove what ran, not what was meant).src/lib.rsfront and center), imposing the role on users who never take it. A wiring-only project tier (Aura.toml + blueprints/ + runs/, no crate ceremony; the crate joins when the first native node arrives) is the derived fix — it deliberately re-opens the "a project is always a Rust crate" uniformity (#180-era reading) in favour of role fit.Resolved forks
What the design pass must still produce (open)
processes/,experiments/besideblueprints/; the wiring-only tier) and docs restructured so each role finds its chapter.Status: framing and the forks above are user-ratified (quotes inline); the artifact-vocabulary design pass has not started. This issue is the anchor and decision log for that pass.
Addendum: the block backend already exists (implementation insight for the design pass)
The Blockly litmus test in this issue's body is not hypothetical for the existing graph layer — the introspection contract a block palette needs is already shipped, under other names:
graph introspect --vocabularyis the palette enumeration,--node <T>(ports, kinds, typed bind forms) is the block shapes and docking points, the construction service's eager per-op checks are the snap-fit (an invalid connection is refused at apply time, not at finalize),--unwiredis the shadow-block hint (open slots, by shape), and the op-script document is the artifact such a surface would read and write. A visual frontend would be one more client of the #157 construction service.Consequence for the design pass: the two new artifact types (process, campaign) should ship the SAME introspection contract from day one — enumerate their vocabulary, describe one block's typed slots, validate a partial document, list its open slots — because that contract is what makes the litmus test checkable and any future projection (read-only viewer first) buildable without touching semantics.
Correction/addendum: control flow in the campaign vocabulary — the power axis (ratified)
This issue's body over-restricts resolved fork 1: it reads as if the campaign/process vocabulary carries no control flow at all, with every dynamic need escalating to Rust. That conflated two separable properties of the Blockly model the litmus test borrows from: the STRUCTURAL discipline (closed palette, typed slots, invalid compositions unsnappable) — which the litmus test imports — and the CONTROL-FLOW vocabulary (Scratch has loop/if blocks; it is Turing-complete) — about which the test says nothing. The power question is its own design axis:
Design rationale for P1: it is the same move as domain invariant 5, one level up — the dataflow graph forbids free feedback and allows it only as the explicit, named register (the z^-1 node); the campaign forbids free control flow and allows it only as explicit, named, bounded constructs (gate, ladder). No new principle, the existing one applied consistently. Precedent that this power tier covers a large practical domain: SQL — not Turing-complete, carries the analytics world; a campaign is semantically closer to a query over the space of possible runs than to a program.
Cost, stated honestly: with gates the EXECUTED run-set becomes data-dependent (only the possible set stays enumerable up front) — no worse than walk-forward's existing sequential dependency; content-addressability, termination, and block-snappability survive intact. The bright line to P2: predicates only over declared metrics, iteration only over declared finite sets, no variables.
Corrected role of the Rust escalation (role 2): it exists for new LOGIC (metrics, analysis blocks), not for flow control — flow control lives in the vocabulary as total constructs.
Fork triage: artifact-vocabulary design (grounded stance review, 2026-07-03)
The eight open forks of the artifact-vocabulary design were populated by five adversarial design lenses (minimalist / composability / maintainer / feature-skeptic / off-ledger wildcard), each grounding its answers in the design ledger, glossary, code, and this issue. Where the lenses converged on a citable shared ground, the fork is decided below (veto by replying here); where they split — or where the pre-review enumeration had independently held a fork open — it is listed as open and awaits a decision.
Decided (with grounds)
Serialization: canonical JSON for both document types. Ground: C24's canonical form (
blueprint_to_json,format_versionenvelope, omit-defaults JSON) and the glossary'scontent id(SHA-256 over canonical JSON bytes) are the one shipped canonicalization;Aura.toml/TOML is ratified as "static project context, never logic" (C16), while these documents carry P1 control constructs — logic-shaped data. Consequence: both document types get aformat_versionenvelope and a content id through the same hashing primitive the blueprint store andgraph introspect --content-idalready use. (Whether a debug-name-blind identity id also applies is a vocabulary-spec detail: the document format decides which fields are identity-bearing.)Presentation in the campaign document is data-level only. The document declares what to record and emit — taps to persist, metrics/comparison tables to produce — and nothing about rendering; rendering stays a viewer-side, stateless projection. Ground: C22 "displayable = exactly what a sink recorded" plus C14's headless core; a chart/layout spec inside the document is foreclosed by C22's forbids (scene-editor model), and "no presentation at all" is foreclosed by this issue's body, which names presentation as one of the campaign's five components.
The process vocabulary is extensible by design and ships std-only. Block ids are namespaced like node type ids; the project-cdylib vocabulary-merge pattern (shipped cycle 0102 for nodes) is the designated extension mechanism, but the first cut ships only the compiled-in std block set. Ground: this issue's ratified role-2 escalation ("new logic = a new Rust block" authored in a project/shared crate) requires project extension eventually; C16's three-tier reuse gradient plus the shipped 0102 merge resolver are the proven mechanism; and the node vocabulary's own history (closed std set first, project merge later) is the shipping pattern. Guardrail recorded: std processes double as vetted reference methodologies, and a project-extended block is visibly namespaced inside any document that uses it — methodology audits stay honest (role 5's anti-false-discovery guard).
Reproducibility is layered: the document is intent, the registry records realization. A campaign document (content-addressed) declares the possible run-set; executing it appends a campaign-level record to the registry naming the realized run-set, whose members already carry per-run manifests (C18). Ground: C18 forbids results not reproducible from a recorded manifest; walk-forward's sequential data-dependence already uses exactly this manifest-layered pattern (
reproducere-derives members from stored manifests, #158/#173); a separate "frozen campaign" artifact would duplicate the registry's existing mechanism. P1 gates make the executed set data-dependent — same shape, same remedy.The v1 process vocabulary wraps what exists — no invented taxonomy. The first block set is a thin named layer over the shipped analysis/selection primitives: the R metrics reduction (
summarize_r/r_metrics_from_rs), the selection rules (argmax, plateau:mean, plateau:worst, deflated), cross-instrument generalization, and the R-bootstrap Monte-Carlo. Ground: these primitives are shipped, named in the C16/C21 realization notes, and live in aura-analysis / aura-registry; designing a container vocabulary for content that was never inventoried is the over-engineering failure the closed vocabulary exists to prevent.First-cycle scope: vocabulary + parse + validate + introspection contract — no executor. Both document types ship the op-script-precedent introspection surface from day one: enumerate the vocabulary, describe one block's typed slots, validate a partial document, list its open slots — the Blockly litmus test made checkable. Ground: the addendum comment of 2026-07-03 12:02 on this issue states this directly, and the shipped sequencing precedent is the construction service itself (#157: build+introspect in cycle 0088, execution meaning for blueprint data only in cycle 0092/#165). Additionally recorded: before any executor is scoped, the need is re-tested against the diagnosis in this issue's body — the named defect is missing persistence of intent, not missing execution (the existing verbs already execute headlessly). A validated, persisted campaign document plus per-stage dispatch of the existing machinery may close the diagnosed gap with a far smaller executor than assumed.
Incremental authoring rides on the introspection contract, not on a session service. A construction-service analogue for campaigns (op-list
campaign build) is not part of the first cycle: validate-partial plus open-slots already gives incremental authoring feedback for flat documents. Watch-item, not a rejection: if campaign documents grow deep enough (nested stages, large gate chains), an op-session path can be added later on the #157 pattern.Confirmed ledger/glossary drift, in scope for this pass's amendment list: the glossary
experimententry still defines a Rust builder-API artifact (the mis-typed thread this issue re-cuts), and the glossaryplaygroundentry still says egui-native while the settled C22 realization is the web-from-disk face. Both entries are to be amended when the ledger amendments land.Open — awaiting a decision (direction forks)
A. Fate of the existing orchestration verbs (
sweep,mc,walkforward,generalize) once campaigns exist. The lenses split four ways, each with support: (i) keep as-is, additive-only — the #157 precedent added the data surface without touching the builder path; (ii) re-implement as thin sugar over an internally generated campaign document — one execution path, no dual-maintenance drift, the same retirement logic C20/C24 already apply to hard-wired harness scaffolding; (iii) deprecate and retire once campaigns subsume them — the #159 pattern; plus the sharpening that the four verbs need not share one fate (e.g.generalizecould fold into a campaign gate whilesweepstays a quick probe verb). This shapes the everyday CLI surface; no source settles it.B. Code home for the new artifact layer (document types, validation, introspection). A new leaf crate (precedent: the aura-analysis extraction, #136; semantic fit: neither the sim substrate nor the run store owns document vocabularies) versus extending aura-registry (which already holds selection and lineage). Notably both sides cite the same C16 cycle-0080 clause in opposite directions ("registry stays the domain-aware selection layer" vs "the orchestration substrate is deferred to a World/C21 layer, explicitly not the registry") — a genuine 2:2 split, so it is put up rather than derived. Recommendation on record: new leaf crate. The executor's home is not part of this fork — deferred until an executor is scoped at all (see Decided 6).
C. May a campaign inline an anonymous process, or does it always reference a named process document? Reference-only (recommendation): this issue's body names "process references" as the campaign field; the diagnosis's cure is a nameable, versionable, referenceable methodology object; and the one-off case is served by a process document with a disposable name — no second mechanism, litmus-clean. Inline-anonymous (counter-voice, explicitly preference-based): avoids indirection ceremony during quick exploration. Held open deliberately: the ceremony-vs-convenience trade is a taste call no source settles outright.
Status: the decided forks above fix the design skeleton (formats, ids, introspection contract, reproducibility story, v1 block inventory, first-cycle scope); items A–C are open and gate the vocabulary spec.
Direction forks resolved (user decisions, 2026-07-03)
The three forks left open by the fork-triage comment on this issue (items A–C there) are resolved:
sweep,mc,walkforward,generalize): dissolve them into the campaign path, but only once it demonstrably carries — "Das Ziel muss sein, das bestehende im Neuen aufzulösen - aber erst wenn das Neue trägt" (user, 2026-07-03). Reading on record: campaigns become the canonical orchestration path; a verb is re-cut as thin sugar over a generated campaign document only when (not before) the campaign substrate reproduces its behaviour, and retires on the #159 pattern afterwards; until then the verbs stay untouched. The "once it carries" gate applies naturally per verb — each dissolves when the campaign path covers it.Status: all direction forks of the artifact-vocabulary design are resolved. The design basis is now the issue body + both addenda + the fork-triage comment's decided items + the three choices above — settled, ready for spec production of the first cycle (both document vocabularies, parse/validate, the introspection contract, content-addressing; no executor).
Amendment package landed (2026-07-03)
The ledger amendments this issue's 'What the design pass must still produce' listed are in: a C25 role-model contract entry (nine roles, recognizability test, text-first/headless-first invariant, Blockly litmus test), the C20 re-read (experiment intent = campaign-document data; the mini-DSL forbid scoped to open logic-bearing languages), the C22 stateless-projection refinement (+ the stale egui playground glossary entry aligned to the web-from-disk face), and the domain-invariant-10 clarification in the project charter (closed-vocabulary data artifacts are not the forbidden DSL). Together with the cycle that shipped both document vocabularies (#189: parse, two-tier validation, introspection contract, content-addressed stores — see the C18 realization note), the pass's artifact-vocabulary and durable-record halves are complete. Still open from the original list: role homes in the project layout (processes/, experiments/, the wiring-only project tier — re-opens 'a project is always a Rust crate') and docs restructured by role; the executor question stays deliberately unscoped until re-tested against the intent-persistence diagnosis; the existing orchestration verbs dissolve into the campaign path only once it demonstrably carries (user decision, 2026-07-03).
The role-model design pass this issue anchored is ratified and shipped. Its content now lives as ledger contract C25 in docs/design/INDEX.md (the nine roles, the recognizability test, the 6a/6b split, and the text-first/headless-first invariant with the Blockly litmus test). The two concrete deliverables this issue's "what the design pass must still produce" section called for have both landed:
processes/andcampaigns/besideblueprints/(docs/design/INDEX.md, C25 realization note and the #189 realization note above C25).The design lineage this issue opened continues actively, just under later issues: #295 (closed, merged) extended the same text-first/control-surface framing to the CLI itself, recorded as a 2026-07-20 amendment directly on C25 (docs/design/INDEX.md:2523-2531); #300 (open) carries the document-first completion that amendment set in motion.
One thread from this issue's original scope remains open and is recorded in the ledger itself: C25 still lists roles 4 (data curator), 7 (player), and 8 (operator/auditor) as 'technically present but faceless (no addressed verb families yet)', with role homes in the project layout and docs-by-role open (docs/design/INDEX.md:2519-2522, #192 context). That standing gap lives in the contract's own realization notes; it warrants a fresh, concretely scoped issue only when that work is actually picked up. This issue's own deliverables are complete — closed as superseded by C25 + #189 + #192 + #241 + #295/#300.