spec: 0106 fix — axis declares its kind once, values are bare JSON
User veto (2026-07-03) of the per-cell tagged Scalar draft: the kind is a
property of the parameter, not of each value. An axis is now
{"kind": "I64", "values": [8, 12, 16]} — mixed-kind axes are
unrepresentable, canonical form normalizes value spelling, and the
referential kind check is one comparison per axis. Op-script binds keep
their tagged form (single-value slots). Decision log: #189.
refs #189
This commit is contained in:
@@ -126,8 +126,8 @@ resolution comment):
|
||||
},
|
||||
"strategies": [
|
||||
{ "ref": { "content_id": "9f3a…" },
|
||||
"axes": { "fast": [{"I64": 8}, {"I64": 12}, {"I64": 16}],
|
||||
"slow": [{"I64": 21}, {"I64": 34}] } }
|
||||
"axes": { "fast": { "kind": "I64", "values": [8, 12, 16] },
|
||||
"slow": { "kind": "I64", "values": [21, 34] } } }
|
||||
],
|
||||
"process": { "ref": { "content_id": "4e2d…" } },
|
||||
"seed": 1,
|
||||
@@ -213,13 +213,21 @@ pub struct CampaignDoc {
|
||||
|
||||
#[derive(Serialize, Deserialize, ...)]
|
||||
pub enum DocRef { ContentId(String), IdentityId(String) } // one-of, typed slots
|
||||
pub struct StrategyEntry { pub r#ref: DocRef, pub axes: BTreeMap<String, Vec<Scalar>> }
|
||||
pub struct StrategyEntry { pub r#ref: DocRef, pub axes: BTreeMap<String, Axis> }
|
||||
pub struct Axis { pub kind: ScalarKind, pub values: Vec<Scalar> }
|
||||
// custom serde: `{"kind": "I64", "values": [8, 12, 16]}` — values are bare
|
||||
// JSON, parsed AS the declared kind
|
||||
pub enum EmitKind { FamilyTable, SelectionReport } // closed v1 set
|
||||
```
|
||||
|
||||
Axis cells are typed `aura_core::Scalar` values — the same typed-cell
|
||||
pattern the op-script binds use (`OpDoc::Add { bind: BTreeMap<String,
|
||||
Scalar> }`, crates/aura-cli/src/graph_construct.rs:37).
|
||||
An axis declares its `ScalarKind` **once** — the kind is a property of the
|
||||
parameter, not of each value (user veto, 2026-07-03, of a per-cell tagged
|
||||
draft), so a mixed-kind axis is unrepresentable rather than merely refused.
|
||||
The op-script binds keep their per-cell tagged `Scalar` form
|
||||
(`OpDoc::Add { bind: BTreeMap<String, Scalar> }`,
|
||||
crates/aura-cli/src/graph_construct.rs:37): a bind slot holds exactly one
|
||||
value, so there the tag is the only kind carrier; an axis is a homogeneous
|
||||
list, so the kind belongs to the axis.
|
||||
|
||||
### Validation, canonical form, introspection (secondary shapes)
|
||||
|
||||
@@ -254,8 +262,10 @@ pub fn put_campaign(…) / get_campaign(…); // same pattern as pu
|
||||
pub fn validate_campaign_refs(doc: &CampaignDoc, roots: &StoreRoots)
|
||||
-> Vec<RefFault>;
|
||||
// RefFault: ProcessNotFound(id), StrategyNotFound(id), IdentityAmbiguityEmpty(id),
|
||||
// AxisNotInParamSpace{strategy_ref, axis} — axes ⊆ the referenced blueprint's
|
||||
// param_space (blueprint loaded from the store via blueprint_from_json).
|
||||
// AxisNotInParamSpace{strategy_ref, axis}, AxisKindMismatch{strategy_ref, axis}
|
||||
// — axes ⊆ the referenced blueprint's param_space, and each axis's declared
|
||||
// kind must equal the param's ScalarKind (one check per axis; blueprint
|
||||
// loaded from the store via blueprint_from_json).
|
||||
```
|
||||
|
||||
Intrinsic P1 constraints enforced (the ratified ceiling made structural):
|
||||
|
||||
Reference in New Issue
Block a user