//! Isolated finite-model experiment. Not Studio syntax or production admission. use std::collections::{BTreeMap, BTreeSet}; use std::fs; use std::path::{Path, PathBuf}; type Result = std::result::Result; #[derive(Clone, Debug, PartialEq, Eq)] struct Definition { member: String, class: String, layer: String, fields: Vec, refs: Vec, } #[derive(Clone, Debug, PartialEq, Eq)] struct Package { identity: String, version: String, raw: String, digest: String, definitions: BTreeMap, description: String, prototype: BTreeMap, selected: BTreeSet, role_member: Option, } impl Package { fn parse(raw: String) -> Result { let mut identity = None; let mut version = None; let mut definitions = BTreeMap::new(); let mut description = None; let mut prototype = BTreeMap::new(); let mut selected = BTreeSet::new(); let mut role_member = None; for line in raw.lines() { let row: Vec<_> = line.split('|').collect(); match row.as_slice() { ["package", p, v] if identity.is_none() => { identity = Some((*p).into()); version = Some((*v).into()); } ["description", text] if description.is_none() => { description = Some((*text).into()) } ["def", member, class, layer, fields, refs] => { let def = Definition { member: (*member).into(), class: (*class).into(), layer: (*layer).into(), fields: split(fields), refs: split(refs), }; if definitions.insert((*member).into(), def).is_some() { return Err("duplicate member".into()); } } ["prototype", member, ..] => { let record = Record::parse(line.splitn(3, '|').nth(2).ok_or("bad prototype")?)?; if record.id != *member || prototype.insert((*member).into(), record).is_some() { return Err("duplicate or mismatched prototype member".into()); } } ["pattern", "monitor", members] if selected.is_empty() => { selected = split(members).into_iter().collect() } ["role", "sink", member, "Activity", "OA"] if role_member.is_none() => { role_member = Some((*member).into()) } ["note", _] | ["analysis", "P", "K", "C"] => {} _ => return Err(format!("unrecognized package row: {line}")), } } let value = Self { identity: identity.ok_or("missing package identity")?, version: version.ok_or("missing version")?, digest: sha256(raw.as_bytes()), raw, definitions, description: description.ok_or("missing description")?, prototype, selected, role_member, }; for def in value.definitions.values() { if !matches!( def.class.as_str(), "Kind" | "Unit" | "Scalar" | "Item" | "Field" | "Interface" | "Allocation" ) { return Err("unsupported contract class".into()); } if def.refs.iter().any(|r| !value.definitions.contains_key(r)) { return Err("unresolved package reference".into()); } } if value .selected .iter() .any(|member| !value.prototype.contains_key(member)) || value .role_member .as_ref() .is_some_and(|m| !value.prototype.contains_key(m) || value.selected.contains(m)) { return Err("incomplete prototype/export/role".into()); } Ok(value) } fn contract(&self, root: &str) -> Result> { let mut pending = vec![root.to_string()]; let mut seen = BTreeSet::new(); while let Some(id) = pending.pop() { if seen.insert(id.clone()) { pending.extend( self.definitions .get(&id) .ok_or("missing contract root")? .refs .clone(), ); } } Ok(seen.iter().map(|id| self.definitions[id].clone()).collect()) } } fn equivalent(a: &Package, am: &str, b: &Package, bm: &str) -> bool { a.identity == b.identity && am == bm && a.contract(am) .ok() .zip(b.contract(bm).ok()) .is_some_and(|(a, b)| a == b) } #[derive(Clone, Debug)] enum Policy { Strict, SameOrigin, Bridges(BTreeSet<(String, String)>), } fn pair(a: &str, b: &str) -> (String, String) { if a <= b { (a.into(), b.into()) } else { (b.into(), a.into()) } } fn policy_matches(a: &Package, am: &str, b: &Package, bm: &str, policy: &Policy) -> bool { if a.identity == b.identity && a.digest == b.digest && am == bm { return true; } match policy { Policy::Strict => false, Policy::SameOrigin => equivalent(a, am, b, bm), Policy::Bridges(witnesses) => { equivalent(a, am, b, bm) && witnesses.contains(&pair( &format!("{}:{am}", a.digest), &format!("{}:{bm}", b.digest), )) } } } #[derive(Clone, Debug, PartialEq, Eq)] struct DRef { import: String, member: String, } impl DRef { fn new(import: &str, member: &str) -> Self { Self { import: import.into(), member: member.into(), } } fn text(&self) -> String { format!("{}:{}", self.import, self.member) } fn parse(s: &str) -> Result { let (i, m) = s.split_once(':').ok_or("bad definition reference")?; Ok(Self::new(i, m)) } } #[derive(Clone, Debug, PartialEq, Eq)] struct Literal { magnitude: i64, unit: DRef, } impl Literal { fn new(magnitude: i64, import: &str, unit: &str) -> Self { Self { magnitude, unit: DRef::new(import, unit), } } fn text(&self) -> String { format!("{}@{}", self.magnitude, self.unit.text()) } fn parse(s: &str) -> Result { let (n, u) = s.split_once('@').ok_or("bad literal")?; Ok(Self { magnitude: n.parse().map_err(|_| "bad integer")?, unit: DRef::parse(u)?, }) } } #[derive(Clone, Debug, PartialEq, Eq)] enum Body { Activity { description: String, }, Interaction { source: String, target: String, item: String, }, Property { subject: String, kind: DRef, base: Literal, }, Case { subject: Option, overrides: BTreeMap, }, Check { property: String, limit: Literal, }, Budget { left: String, right: String, kind: DRef, limit: Literal, }, Consumer { exchange: String, interface: String, allocation: String, field: String, }, } #[derive(Clone, Debug, PartialEq, Eq)] struct Record { id: String, layer: String, name: String, body: Body, } impl Record { fn line(&self) -> String { let tail = match &self.body { Body::Activity { description } => format!("Activity|{description}"), Body::Interaction { source, target, item, } => format!("Interaction|{source}|{target}|{item}"), Body::Property { subject, kind, base, } => format!("Property|{subject}|{}|{}", kind.text(), base.text()), Body::Case { subject, overrides } => format!( "Case|{}|{}", subject.as_deref().unwrap_or("-"), overrides .iter() .map(|(p, e)| format!("{p}={}", e.text())) .collect::>() .join(",") ), Body::Check { property, limit } => format!("Check|{property}|{}", limit.text()), Body::Budget { left, right, kind, limit, } => format!("Budget|{left}|{right}|{}|{}", kind.text(), limit.text()), Body::Consumer { exchange, interface, allocation, field, } => format!("Consumer|{exchange}|{interface}|{allocation}|{field}"), }; format!("record|{}|{}|{}|{tail}", self.id, self.layer, self.name) } fn parse(line: &str) -> Result { let r: Vec<_> = line.split('|').collect(); if r.len() < 5 || r[0] != "record" { return Err("bad record".into()); } let body = match &r[4..] { ["Activity", description] => Body::Activity { description: (*description).into(), }, ["Interaction", source, target, item] => Body::Interaction { source: (*source).into(), target: (*target).into(), item: (*item).into(), }, ["Property", subject, kind, value] => Body::Property { subject: (*subject).into(), kind: DRef::parse(kind)?, base: Literal::parse(value)?, }, ["Case", subject, rows] => { let mut overrides = BTreeMap::new(); for row in split(rows) { let (id, value) = row.split_once('=').ok_or("bad override")?; if overrides .insert(id.into(), Literal::parse(value)?) .is_some() { return Err("duplicate override".into()); } } Body::Case { subject: (*subject != "-").then(|| (*subject).into()), overrides, } } ["Check", property, limit] => Body::Check { property: (*property).into(), limit: Literal::parse(limit)?, }, ["Budget", left, right, kind, limit] => Body::Budget { left: (*left).into(), right: (*right).into(), kind: DRef::parse(kind)?, limit: Literal::parse(limit)?, }, ["Consumer", exchange, interface, allocation, field] => Body::Consumer { exchange: (*exchange).into(), interface: (*interface).into(), allocation: (*allocation).into(), field: (*field).into(), }, _ => return Err("bad constructor".into()), }; Ok(Self { id: r[1].into(), layer: r[2].into(), name: r[3].into(), body, }) } fn remap_live(&mut self, old: &str, new: &str) { fn remap(id: &mut String, old: &str, new: &str) { if id == old { *id = new.into(); } } remap(&mut self.id, old, new); match &mut self.body { Body::Activity { .. } => {} Body::Interaction { source, target, item, } => { remap(source, old, new); remap(target, old, new); remap(item, old, new); } Body::Property { subject, .. } => remap(subject, old, new), Body::Case { subject, overrides } => { if let Some(subject) = subject { remap(subject, old, new); } if let Some(v) = overrides.remove(old) { overrides.insert(new.into(), v); } } Body::Check { property, .. } => remap(property, old, new), Body::Budget { left, right, .. } => { remap(left, old, new); remap(right, old, new); } Body::Consumer { exchange, interface, allocation, field, } => { remap(exchange, old, new); remap(interface, old, new); remap(allocation, old, new); remap(field, old, new); } } } fn rebind_self_definitions(&mut self, import: &str) { fn reference(r: &mut DRef, import: &str) { if r.import == "SELF" { r.import = import.into(); } } fn literal(l: &mut Literal, import: &str) { reference(&mut l.unit, import); } match &mut self.body { Body::Property { kind, base, .. } => { reference(kind, import); literal(base, import); } Body::Case { overrides, .. } => { for value in overrides.values_mut() { literal(value, import); } } Body::Check { limit, .. } => literal(limit, import), Body::Budget { kind, limit, .. } => { reference(kind, import); literal(limit, import); } Body::Activity { .. } | Body::Interaction { .. } | Body::Consumer { .. } => {} } } } #[derive(Clone, Debug, PartialEq, Eq)] struct Mount { import: String, members: BTreeMap, } #[derive(Clone, Debug, PartialEq, Eq)] struct Instance { import: String, mount: String, sink: String, prefix: String, original: BTreeMap, current: BTreeMap>, lineage: BTreeMap, base: BTreeMap, } #[derive(Clone, Debug, PartialEq, Eq)] struct Document { identity: String, revision: u32, imports: BTreeMap, mounts: BTreeMap, instances: BTreeMap, live: BTreeMap, receipts: Vec, } fn materialize(instance: &Instance, package: &Package, mount: &Mount) -> BTreeMap { package .selected .iter() .map(|member| { let mut record = package.prototype[member].clone(); for (foreign, local) in &instance.original { record.remap_live(foreign, local); } if let Some(role_member) = &package.role_member { record.remap_live(role_member, &instance.sink); } for (foreign, local) in &mount.members { record.remap_live(&format!("MOUNT/{foreign}"), local); } record.rebind_self_definitions(&instance.import); record.name = format!("{} {}", instance.prefix, record.name); (member.clone(), record) }) .collect() } fn split(s: &str) -> Vec { if s.is_empty() || s == "-" { vec![] } else { s.split(',').map(String::from).collect() } } fn read(path: &Path) -> Result { fs::read_to_string(path).map_err(|e| format!("{}: {e}", path.display())) } fn write(path: &Path, text: &str) -> Result<()> { if let Some(parent) = path.parent() { fs::create_dir_all(parent).map_err(|e| e.to_string())?; } fs::write(path, text).map_err(|e| e.to_string()) } fn prepare_new(request: &str, packages: &BTreeMap) -> Result { let mut doc = Document { identity: String::new(), revision: 1, imports: BTreeMap::new(), mounts: BTreeMap::new(), instances: BTreeMap::new(), live: BTreeMap::new(), receipts: vec![], }; for line in request.lines() { let r: Vec<_> = line.split('|').collect(); match r.as_slice() { ["new", id] if doc.identity.is_empty() => doc.identity = (*id).into(), ["import", alias, package] => { if doc .imports .insert( (*alias).into(), packages .get(*package) .ok_or("missing supplied package")? .clone(), ) .is_some() { return Err("duplicate import".into()); } } ["mount", id, import] => { let p = doc.imports.get(*import).ok_or("missing import")?; let members = p .definitions .values() .filter(|d| d.layer == "OA") .map(|d| (d.member.clone(), format!("{id}/{}", d.member))) .collect(); if doc .mounts .insert( (*id).into(), Mount { import: (*import).into(), members, }, ) .is_some() { return Err("duplicate mount".into()); } } ["activity", id, name] => { doc.live.insert( (*id).into(), Record { id: (*id).into(), layer: "OA".into(), name: (*name).into(), body: Body::Activity { description: String::new(), }, }, ); } ["instantiate", id, import, mount, sink] => { if !doc.live.contains_key(*sink) { return Err("missing role binding".into()); } let original: BTreeMap = ["A", "E", "P", "C", "K"] .into_iter() .map(|m| (m.into(), format!("{id}/{m}"))) .collect(); let mut instance = Instance { import: (*import).into(), mount: (*mount).into(), sink: (*sink).into(), prefix: (*id).into(), current: original .iter() .map(|(m, id)| (m.clone(), Some(id.clone()))) .collect(), lineage: original .values() .map(|id| (id.clone(), id.clone())) .collect(), original, base: BTreeMap::new(), }; let mount = doc.mounts.get(*mount).ok_or("missing mount")?; if mount.import != *import { return Err("initial mount pin mismatch".into()); } instance.base = materialize( &instance, doc.imports.get(*import).ok_or("missing import")?, mount, ); for r in instance.base.values() { if doc.live.insert(r.id.clone(), r.clone()).is_some() { return Err("identity collision".into()); } } if doc.instances.insert((*id).into(), instance).is_some() { return Err("duplicate instance".into()); } } ["budget", id, left, right, import] => { doc.live.insert( (*id).into(), Record { id: (*id).into(), layer: "OA".into(), name: "Combined duration".into(), body: Body::Budget { left: (*left).into(), right: (*right).into(), kind: DRef::new(import, "Duration"), limit: Literal::new(2000, import, "ms"), }, }, ); } ["consumer", id, exchange, mount] => { let m = doc.mounts.get(*mount).ok_or("missing consumer mount")?; doc.live.insert( (*id).into(), Record { id: (*id).into(), layer: "OA".into(), name: "Outside typed receiver".into(), body: Body::Consumer { exchange: (*exchange).into(), interface: m.members["Interface"].clone(), allocation: m.members["Operation"].clone(), field: m.members["Code"].clone(), }, }, ); } ["global_case", id, property] => { doc.live.insert( (*id).into(), Record { id: (*id).into(), layer: "OA".into(), name: "Unrelated project-wide study".into(), body: Body::Case { subject: None, overrides: BTreeMap::from([( (*property).into(), Literal::new(3000, "controls1", "ms"), )]), }, }, ); } ["receipt", id] => doc.receipts.push((*id).into()), _ => return Err(format!("unsupported request row: {line}")), } } admit(&doc)?; Ok(doc) } fn admit(doc: &Document) -> Result<()> { let mut identities: BTreeSet = doc.live.keys().cloned().collect(); let mut labels = BTreeMap::new(); for (alias, p) in &doc.imports { if sha256(p.raw.as_bytes()) != p.digest { return Err(format!("wrong package bytes: {alias}")); } if Package::parse(p.raw.clone())? != *p { return Err("forged parsed package".into()); } if let Some(prior) = labels.insert((p.identity.clone(), p.version.clone()), p.digest.clone()) && prior != p.digest { return Err("same package/version has conflicting bytes".into()); } } for mount in doc.mounts.values() { let p = doc .imports .get(&mount.import) .ok_or("missing mount package")?; let required: BTreeSet<_> = p .definitions .values() .filter(|d| d.layer == "OA") .map(|d| d.member.clone()) .collect(); if required != mount.members.keys().cloned().collect() { return Err("mount not complete".into()); } for id in mount.members.values() { if !identities.insert(id.clone()) { return Err("mount identity collision".into()); } } } let mut tracked = BTreeSet::new(); for instance in doc.instances.values() { let p = doc .imports .get(&instance.import) .ok_or("missing base package")?; let m = doc .mounts .get(&instance.mount) .ok_or("missing base mount")?; if m.import != instance.import { return Err("base mount pin mismatch".into()); } if instance.original.keys().cloned().collect::>() != BTreeSet::from(["A", "E", "P", "C", "K"].map(String::from)) { return Err("incomplete original map".into()); } if materialize(instance, p, m) != instance.base { return Err("forged historical base".into()); } if instance.current.keys().ne(instance.original.keys()) { return Err("incomplete correspondence".into()); } for (member, live) in &instance.current { let original = &instance.original[member]; if let Some(id) = live { if id != original && identities.contains(original) { return Err("historical local identity was reused".into()); } if !tracked.insert(id.clone()) || !doc.live.contains_key(id) { return Err("bad current map".into()); } if instance.lineage.get(original) != Some(id) { return Err("missing typed lineage".into()); } if std::mem::discriminant(&doc.live[id].body) != std::mem::discriminant(&instance.base[member].body) { return Err("record class changed".into()); } } else if identities.contains(original) { return Err("deleted identity was reused".into()); } } } for r in doc.live.values() { let required = match &r.body { Body::Activity { .. } => vec![], Body::Interaction { source, target, item, } => vec![source, target, item], Body::Property { subject, kind, base, } => { kind_compatible(doc, kind, &unit_kind(doc, &base.unit)?)? .then_some(()) .ok_or("property unit kind mismatch")?; vec![subject] } Body::Case { subject, overrides } => { let mut ids: Vec<_> = overrides.keys().collect(); if let Some(s) = subject { ids.push(s); } for (id, literal) in overrides { let Body::Property { kind, .. } = &doc.live.get(id).ok_or("missing override property")?.body else { return Err("wrong override kind".into()); }; if !kind_compatible(doc, kind, &unit_kind(doc, &literal.unit)?)? { return Err("override unit kind mismatch".into()); } } ids } Body::Check { property, .. } => vec![property], Body::Budget { left, right, .. } => vec![left, right], Body::Consumer { exchange, interface, allocation, field, } => vec![exchange, interface, allocation, field], }; if required.iter().any(|id| !identities.contains(*id)) { return Err(format!("dangling live reference in {}", r.id)); } } evaluate(doc, "budget")?; consumer_match(doc, "outside")?; Ok(()) } fn kind_compatible(doc: &Document, a: &DRef, b: &DRef) -> Result { let pa = doc.imports.get(&a.import).ok_or("missing kind import")?; let pb = doc.imports.get(&b.import).ok_or("missing kind import")?; Ok(pa .definitions .get(&a.member) .is_some_and(|d| d.class == "Kind") && pb .definitions .get(&b.member) .is_some_and(|d| d.class == "Kind") && equivalent(pa, &a.member, pb, &b.member)) } fn unit_kind(doc: &Document, unit: &DRef) -> Result { let p = doc.imports.get(&unit.import).ok_or("missing unit import")?; let d = p.definitions.get(&unit.member).ok_or("missing unit")?; if d.class != "Unit" || d.refs.len() != 1 { return Err("wrong unit kind".into()); } Ok(DRef::new(&unit.import, &d.refs[0])) } fn millis(doc: &Document, literal: &Literal) -> Result { let p = doc .imports .get(&literal.unit.import) .ok_or("missing unit import")?; let d = p .definitions .get(&literal.unit.member) .ok_or("missing unit")?; let scale = d .fields .first() .ok_or("missing scale")? .strip_prefix("millis=") .ok_or("bad scale")? .parse::() .map_err(|_| "bad scale")?; literal .magnitude .checked_mul(scale) .ok_or("overflow".into()) } fn evaluate(doc: &Document, id: &str) -> Result<(i64, bool)> { evaluate_policy(doc, id, &Policy::SameOrigin) } fn evaluate_check(doc: &Document, check: &str, context: Option<&str>) -> Result<(i64, bool)> { let Body::Check { property, limit } = &doc.live.get(check).ok_or("missing check")?.body else { return Err("not check".into()); }; let Body::Property { kind, base, .. } = &doc.live.get(property).ok_or("missing property")?.body else { return Err("not property".into()); }; let effective = if let Some(context) = context { let Body::Case { overrides, .. } = &doc.live.get(context).ok_or("missing case")?.body else { return Err("not case".into()); }; overrides.get(property).unwrap_or(base) } else { base }; if !kind_compatible(doc, kind, &unit_kind(doc, &effective.unit)?)? || !kind_compatible(doc, kind, &unit_kind(doc, &limit.unit)?)? { return Err("check kind mismatch".into()); } let value = millis(doc, effective)?; Ok((value, value <= millis(doc, limit)?)) } fn evaluate_policy(doc: &Document, id: &str, policy: &Policy) -> Result<(i64, bool)> { let Body::Budget { left, right, kind, limit, } = &doc.live.get(id).ok_or("missing budget")?.body else { return Err("not budget".into()); }; let mut total = 0i64; for id in [left, right] { let Body::Property { kind: input_kind, base, .. } = &doc.live.get(id).ok_or("missing property")?.body else { return Err("not property".into()); }; let unit_kind = unit_kind(doc, &base.unit)?; if !policy_matches( &doc.imports[&kind.import], &kind.member, &doc.imports[&input_kind.import], &input_kind.member, policy, ) || !policy_matches( &doc.imports[&input_kind.import], &input_kind.member, &doc.imports[&unit_kind.import], &unit_kind.member, policy, ) { return Err("incompatible budget kind".into()); } total += millis(doc, base)?; } Ok((total, total <= millis(doc, limit)?)) } fn mounted<'a>(doc: &'a Document, id: &str) -> Result<(&'a Mount, String)> { for mount in doc.mounts.values() { for (member, local) in &mount.members { if id == local { return Ok((mount, member.clone())); } } } Err("not a mounted member".into()) } fn consumer_match(doc: &Document, id: &str) -> Result> { consumer_match_policy(doc, id, &Policy::SameOrigin) } fn consumer_match_policy( doc: &Document, id: &str, policy: &Policy, ) -> Result> { let Body::Consumer { exchange, interface, allocation, field, } = &doc.live.get(id).ok_or("missing consumer")?.body else { return Err("not consumer".into()); }; let Body::Interaction { item, .. } = &doc.live.get(exchange).ok_or("missing exchange")?.body else { return Err("not exchange".into()); }; let (actual, member) = mounted(doc, item)?; let (expected, expected_interface) = mounted(doc, interface)?; if member != "Alarm" || expected_interface != "Interface" { return Err("wrong contracted root".into()); } let a = &doc.imports[&actual.import]; let e = &doc.imports[&expected.import]; if !policy_matches(a, "Interface", e, "Interface", policy) { return Err("item/interface not compatible".into()); } if expected.members.get("Operation") != Some(allocation) || expected.members.get("Code") != Some(field) { return Err("operation or field outside declared root".into()); } Ok(expected .members .iter() .map(|(member, local)| (local.clone(), actual.members[member].clone())) .collect()) } fn apply_edit(doc: &Document, request: &str) -> Result { let r: Vec<_> = request.trim().split('|').collect(); let ["edit_base", id, literal] = r.as_slice() else { return Err("bad edit request".into()); }; let mut candidate = doc.clone(); let Body::Property { base, .. } = &mut candidate .live .get_mut(*id) .ok_or("missing edit target")? .body else { return Err("not property".into()); }; *base = Literal::parse(literal)?; candidate.revision += 1; candidate.receipts.push(request.trim().into()); admit(&candidate)?; Ok(candidate) } fn merge_value(base: &T, local: &T, next: &T, keep_local: bool) -> Result { if local == base { Ok(next.clone()) } else if next == base || local == next || keep_local { Ok(local.clone()) } else { Err("unresolved typed value conflict".into()) } } fn update(doc: &Document, request: &str, package: Package) -> Result { let r: Vec<_> = request.trim().split('|').collect(); let [ "update", id, old_digest, new_import, new_mount, expected_revision, choice, ] = r.as_slice() else { return Err("bad update request".into()); }; if expected_revision .parse::() .map_err(|_| "bad revision")? != doc.revision { return Err("stale revision".into()); } let old = doc.instances.get(*id).ok_or("missing instance")?; if doc.imports[&old.import].digest != *old_digest { return Err("stale base pin".into()); } let mut candidate = doc.clone(); if candidate.imports.contains_key(*new_import) || candidate.mounts.contains_key(*new_mount) { return Err("immutable import/mount collision".into()); } let mount = Mount { import: (*new_import).into(), members: package .definitions .values() .filter(|d| d.layer == "OA") .map(|d| (d.member.clone(), format!("{new_mount}/{}", d.member))) .collect(), }; let mut next = old.clone(); next.import = (*new_import).into(); next.mount = (*new_mount).into(); next.original = old .current .iter() .map(|(m, id)| { id.clone() .map(|id| (m.clone(), id)) .ok_or("deleted member needs explicit policy") }) .collect::>()?; next.base = materialize(&next, &package, &mount); for (member, incoming) in &next.base { let local_id = old.current[member] .as_ref() .ok_or("missing current member")?; let mut baseline = old.base[member].clone(); for (original, current) in &old.lineage { baseline.remap_live(original, current); } let local = &doc.live[local_id]; let value = if local == &baseline { incoming.clone() } else if incoming == &baseline || incoming == local { local.clone() } else if member == "P" && *choice == "P.base=keep_local" { let ( Body::Property { subject: bs, kind: bk, base: bb, }, Body::Property { subject: ls, kind: lk, base: lb, }, Body::Property { subject: ns, kind: nk, base: nb, }, ) = (&baseline.body, &local.body, &incoming.body) else { return Err("constructor mismatch".into()); }; Record { id: merge_value(&baseline.id, &local.id, &incoming.id, false)?, layer: merge_value(&baseline.layer, &local.layer, &incoming.layer, false)?, name: merge_value(&baseline.name, &local.name, &incoming.name, false)?, body: Body::Property { subject: merge_value(bs, ls, ns, false)?, kind: merge_value(bk, lk, nk, false)?, base: merge_value(bb, lb, nb, true)?, }, } } else { return Err(format!("unresolved typed facet conflict: {member}")); }; candidate.live.insert(value.id.clone(), value); } for id in next.original.values() { next.lineage.insert(id.clone(), id.clone()); } candidate.imports.insert((*new_import).into(), package); candidate.mounts.insert((*new_mount).into(), mount); candidate.instances.insert((*id).into(), next); candidate.revision += 1; candidate.receipts.push(request.trim().into()); admit(&candidate)?; Ok(candidate) } fn save(doc: &Document, dir: &Path) -> Result<()> { let mut source = format!("document|{}|{}\n", doc.identity, doc.revision); for (alias, p) in &doc.imports { let path = format!("packages/{}.library", p.digest); source += &format!( "import|{alias}|{}|{}|{}|{path}\n", p.identity, p.version, p.digest ); write(&dir.join(path), &p.raw)?; } for (id, m) in &doc.mounts { source += &format!("mount|{id}|{}|management/{id}.mount\n", m.import); let body = m .members .iter() .map(|(foreign, local)| format!("member|{foreign}|{local}\n")) .collect::(); write(&dir.join(format!("management/{id}.mount")), &body)?; } for (id, i) in &doc.instances { source += &format!("instance|{id}|management/{id}\n"); let mut base = format!("base|{}|{}|{}|{}\n", i.import, i.mount, i.sink, i.prefix); for (m, original) in &i.original { base += &format!("original|{m}|{original}\n"); } for (m, r) in &i.base { base += &format!("member|{m}|{}\n", r.line()); } write(&dir.join(format!("management/{id}/base.model")), &base)?; let map = i .current .iter() .map(|(m, current)| { format!("current|{m}|{}\n", current.as_deref().unwrap_or("DELETED")) }) .collect::(); write(&dir.join(format!("management/{id}/map.model")), &map)?; let lineage = i .lineage .iter() .map(|(original, current)| format!("lineage|{original}|{current}\n")) .collect::(); write( &dir.join(format!("management/{id}/lineage.model")), &lineage, )?; } for r in doc.live.values() { source += &format!("{}\n", r.line()); } for receipt in &doc.receipts { source += &format!("applied|{receipt}\n"); } write(&dir.join("project.model"), &source) } fn declared(dir: &Path, logical: &str) -> Result { if logical.starts_with('/') || logical.contains('\\') || logical .split('/') .any(|p| p.is_empty() || p == "." || p == ".." || p.contains(':')) { return Err("nonportable logical path".into()); } Ok(dir.join(logical)) } fn load(dir: &Path) -> Result { let mut doc = Document { identity: String::new(), revision: 0, imports: BTreeMap::new(), mounts: BTreeMap::new(), instances: BTreeMap::new(), live: BTreeMap::new(), receipts: vec![], }; for line in read(&dir.join("project.model"))?.lines() { let r: Vec<_> = line.split('|').collect(); match r.as_slice() { ["document", id, rev] => { doc.identity = (*id).into(); doc.revision = rev.parse().map_err(|_| "bad revision")?; } ["import", alias, identity, version, digest, path] => { let p = Package::parse(read(&declared(dir, path)?)?)?; if p.digest != *digest || p.identity != *identity || p.version != *version { return Err("package pin mismatch".into()); } if doc.imports.insert((*alias).into(), p).is_some() { return Err("duplicate import".into()); } } ["mount", id, import, path] => { let mut members = BTreeMap::new(); for line in read(&declared(dir, path)?)?.lines() { let row: Vec<_> = line.split('|').collect(); let ["member", member, local] = row.as_slice() else { return Err("bad mount member".into()); }; if members.insert((*member).into(), (*local).into()).is_some() { return Err("duplicate mount member".into()); } } doc.mounts.insert( (*id).into(), Mount { import: (*import).into(), members, }, ); } ["instance", id, path] => { let mut i = Instance { import: String::new(), mount: String::new(), sink: String::new(), prefix: String::new(), original: BTreeMap::new(), current: BTreeMap::new(), lineage: BTreeMap::new(), base: BTreeMap::new(), }; for line in read(&declared(dir, &format!("{path}/base.model"))?)?.lines() { let row: Vec<_> = line.split('|').collect(); match row.as_slice() { ["base", import, mount, sink, prefix] => { i.import = (*import).into(); i.mount = (*mount).into(); i.sink = (*sink).into(); i.prefix = (*prefix).into(); } ["original", m, local] => { if i.original.insert((*m).into(), (*local).into()).is_some() { return Err("duplicate original".into()); } } ["member", m, ..] => { let body = line.splitn(3, '|').nth(2).ok_or("bad member record")?; if i.base.insert((*m).into(), Record::parse(body)?).is_some() { return Err("duplicate base member".into()); } } _ => return Err("bad base row".into()), } } for line in read(&declared(dir, &format!("{path}/map.model"))?)?.lines() { let row: Vec<_> = line.split('|').collect(); let ["current", m, local] = row.as_slice() else { return Err("bad current row".into()); }; if i.current .insert((*m).into(), (*local != "DELETED").then(|| (*local).into())) .is_some() { return Err("duplicate current row".into()); } } for line in read(&declared(dir, &format!("{path}/lineage.model"))?)?.lines() { let row: Vec<_> = line.split('|').collect(); let ["lineage", old, new] = row.as_slice() else { return Err("bad lineage row".into()); }; if i.lineage.insert((*old).into(), (*new).into()).is_some() { return Err("duplicate lineage row".into()); } } doc.instances.insert((*id).into(), i); } ["record", ..] => { let record = Record::parse(line)?; if doc.live.insert(record.id.clone(), record).is_some() { return Err("duplicate live record".into()); } } ["applied", ..] => doc.receipts.push(line[8..].into()), _ => return Err("unknown normalized row".into()), } } admit(&doc)?; Ok(doc) } #[derive(Clone, Debug, PartialEq, Eq)] struct Transition { layer: String, records: BTreeMap, origin_pin: String, target_pin: Option, origin_map: BTreeMap, mount: bool, } #[derive(Clone, Debug, PartialEq, Eq)] enum TargetRecord { Function { name: String, }, Port { owner: String, direction: String, accepted_item: String, }, FunctionalExchange { source: String, target: String, source_port: String, target_port: String, item: String, }, } fn target_architecture(transition: &Transition) -> Result> { let member = transition .origin_map .get("Alarm") .ok_or("missing item correspondence")?; let item = transition .records .get(member) .ok_or("missing mapped item")?; if transition.layer != "SA" || item.layer != "SA" || item.class != "Item" { return Err("invalid SA item disposition".into()); } let item = if transition.mount { format!("sa_mount/{member}") } else { member.clone() }; Ok(BTreeMap::from([ ( "sa/watch".into(), TargetRecord::Function { name: "Watch".into(), }, ), ( "sa/receive".into(), TargetRecord::Function { name: "Receive left".into(), }, ), ( "sa/watch_out".into(), TargetRecord::Port { owner: "sa/watch".into(), direction: "Out".into(), accepted_item: item.clone(), }, ), ( "sa/receive_in".into(), TargetRecord::Port { owner: "sa/receive".into(), direction: "In".into(), accepted_item: item.clone(), }, ), ( "sa/alarm".into(), TargetRecord::FunctionalExchange { source: "sa/watch".into(), target: "sa/receive".into(), source_port: "sa/watch_out".into(), target_port: "sa/receive_in".into(), item, }, ), ])) } fn derivative(package: &Package) -> Transition { let members = package.definitions.values().filter(|d| d.layer == "OA"); let records = members .map(|d| { let mut copied = d.clone(); copied.layer = "SA".into(); copied.member = format!("SA/{}", d.member); copied.refs = d .refs .iter() .map(|r| { if package.definitions[r].layer == "OA" { format!("SA/{r}") } else { r.clone() } }) .collect(); (copied.member.clone(), copied) }) .collect(); Transition { layer: "SA".into(), records, origin_pin: package.digest.clone(), target_pin: None, origin_map: package .definitions .values() .filter(|d| d.layer == "OA") .map(|d| (d.member.clone(), format!("SA/{}", d.member))) .collect(), mount: false, } } fn pinned_counterpart( package: &Package, target: &Package, correspondence: &BTreeMap, ) -> Result { let expected = derivative(package); let records = target .definitions .values() .filter(|d| d.layer == "SA") .map(|d| (d.member.clone(), d.clone())) .collect(); if expected.records != records || &expected.origin_map != correspondence { return Err("incomplete/incompatible layer correspondence".into()); } Ok(Transition { layer: "SA".into(), records, origin_pin: package.digest.clone(), target_pin: Some(target.digest.clone()), origin_map: correspondence.clone(), mount: true, }) } fn analysis_scope( properties: &[&str], checks: &[&str], cases: &[&str], external: &[&str], ) -> Result> { let mut selected: BTreeSet = properties .iter() .chain(checks) .chain(cases) .map(|s| (*s).into()) .collect(); let boundary: BTreeSet<_> = external.iter().copied().collect(); loop { let old = selected.clone(); for id in &old { let dependencies = match id.as_str() { "P" => vec![], "K" | "C" => vec!["P"], "G" => vec!["P", "Q"], "Q" => vec![], _ => return Err("unknown analysis root".into()), }; selected.extend( dependencies .into_iter() .filter(|id| !boundary.contains(id)) .map(String::from), ); } if selected == old { break; } } if selected.contains("Q") { return Err("outside property Q requires explicit subject/property boundary choice".into()); } Ok(selected) } fn sha256(bytes: &[u8]) -> String { const K: [u32; 64] = [ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, ]; let mut h: [u32; 8] = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, ]; let mut data = bytes.to_vec(); let bit_len = (data.len() as u64) * 8; data.push(0x80); while data.len() % 64 != 56 { data.push(0); } data.extend(bit_len.to_be_bytes()); for chunk in data.chunks_exact(64) { let mut w = [0u32; 64]; for (i, word) in chunk.chunks_exact(4).enumerate() { w[i] = u32::from_be_bytes(word.try_into().expect("four bytes")); } for i in 16..64 { let s0 = w[i - 15].rotate_right(7) ^ w[i - 15].rotate_right(18) ^ (w[i - 15] >> 3); let s1 = w[i - 2].rotate_right(17) ^ w[i - 2].rotate_right(19) ^ (w[i - 2] >> 10); w[i] = w[i - 16] .wrapping_add(s0) .wrapping_add(w[i - 7]) .wrapping_add(s1); } let [mut a, mut b, mut c, mut d, mut e, mut f, mut g, mut hh] = h; for i in 0..64 { let s1 = e.rotate_right(6) ^ e.rotate_right(11) ^ e.rotate_right(25); let ch = (e & f) ^ (!e & g); let t1 = hh .wrapping_add(s1) .wrapping_add(ch) .wrapping_add(K[i]) .wrapping_add(w[i]); let s0 = a.rotate_right(2) ^ a.rotate_right(13) ^ a.rotate_right(22); let maj = (a & b) ^ (a & c) ^ (b & c); let t2 = s0.wrapping_add(maj); hh = g; g = f; f = e; e = d.wrapping_add(t1); d = c; c = b; b = a; a = t1.wrapping_add(t2); } for (state, value) in h.iter_mut().zip([a, b, c, d, e, f, g, hh]) { *state = state.wrapping_add(value); } } h.iter().map(|x| format!("{x:08x}")).collect() } fn main() -> Result<()> { let args: Vec = std::env::args().skip(1).collect(); if args.first().is_some_and(|a| a == "--reopen") { if args.len() != 3 { return Err("usage: --reopen INPUT_DIRECTORY OUTPUT_DIRECTORY".into()); } let doc = load(Path::new(&args[1]))?; let budget = evaluate(&doc, "budget")?; save(&doc, Path::new(&args[2]))?; println!( "Fresh process reopened {} records at revision {}; budget={} ms satisfied={}", doc.live.len(), doc.revision, budget.0, budget.1 ); return Ok(()); } let root = PathBuf::from( args.first() .ok_or("provide the owned experiment output directory")?, ); fs::create_dir_all(&root).map_err(|e| e.to_string())?; let mut checks = 0usize; macro_rules! check { ($condition:expr) => {{ checks += 1; assert!($condition, "check {}: {}", checks, stringify!($condition)); }}; } check!(sha256(b"") == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); check!(sha256(b"abc") == "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); let raw = concat!( "package|ControlPatterns|1.0.0\n", "description|Monitor alarm\n", "note|Initial documentation\n", "def|Duration|Kind|Neutral|dimension=0,0,1,0,0,0,0;linear|-\n", "def|Energy|Kind|Neutral|dimension=2,1,-2,0,0,0,0;linear|-\n", "def|Torque|Kind|Neutral|dimension=2,1,-2,0,0,0,0;linear|-\n", "def|ms|Unit|Neutral|millis=1|Duration\n", "def|s|Unit|Neutral|millis=1000|Duration\n", "def|Flag|Scalar|OA|Boolean|-\n", "def|Alarm|Item|OA|Flow|Code\n", "def|Code|Field|OA|minimum=1;maximum=1|Alarm,Flag\n", "def|Interface|Interface|OA|-|Operation\n", "def|Operation|Allocation|OA|order=0|Interface,Alarm\n", "prototype|A|record|A|OA|Watch|Activity|Monitor alarm\n", "prototype|E|record|E|OA|Alarm|Interaction|A|H|MOUNT/Alarm\n", "prototype|P|record|P|OA|Elapsed|Property|A|SELF:Duration|750@SELF:ms\n", "prototype|C|record|C|OA|Stress|Case|-|P=1250@SELF:ms\n", "prototype|K|record|K|OA|Elapsed limit|Check|P|1000@SELF:ms\n", "prototype|H|record|H|OA|Prototype receiver|Activity|Context role only\n", "prototype|Q|record|Q|OA|Outside delay|Property|H|SELF:Duration|1000@SELF:ms\n", "prototype|G|record|G|OA|Project-wide study|Case|-|P=2500@SELF:ms,Q=4000@SELF:ms\n", "pattern|monitor|A,E,P,C,K\n", "analysis|P|K|C\n", "role|sink|H|Activity|OA\n" ); let p1 = Package::parse(raw.into())?; let p2 = Package::parse( raw.replace("1.0.0", "1.0.1") .replace("Initial documentation", "Revised documentation only"), )?; let p3 = Package::parse( raw.replace("1.0.0", "2.0.0") .replace("maximum=1", "maximum=2"), )?; let changed_kind = Package::parse(raw.replace("dimension=0,0,1,0,0,0,0", "dimension=1,0,0,0,0,0,0"))?; let other = Package::parse(raw.replace("ControlPatterns", "OtherVocabulary"))?; check!(p1.digest != p2.digest && p1.raw != p2.raw); for member in p1.definitions.keys() { check!(equivalent(&p1, member, &p2, member)); } check!(!equivalent(&p1, "Duration", &p1, "Energy")); check!(!equivalent(&p1, "Energy", &p1, "Torque")); check!(!equivalent(&p1, "Duration", &other, "Duration")); check!(!equivalent(&p1, "Duration", &changed_kind, "Duration")); check!(!equivalent(&p1, "Interface", &p3, "Interface")); check!(equivalent(&p1, "Duration", &p3, "Duration")); let packages = BTreeMap::from([("D1".into(), p1.clone()), ("D2".into(), p2.clone())]); let request = "new|Alpha\nimport|controls1|D1\nmount|data1|controls1\nactivity|sink_left|Receive left\nactivity|sink_right|Receive right\ninstantiate|left|controls1|data1|sink_left\ninstantiate|right|controls1|data1|sink_right\nbudget|budget|left/P|right/P|controls1\nconsumer|outside|left/E|data1\nglobal_case|global|left/P\nreceipt|create-two-instances\n"; write(&root.join("initial.request"), request)?; let initial = prepare_new(&read(&root.join("initial.request"))?, &packages)?; let expected_initial_rows = [ "record|sink_left|OA|Receive left|Activity|", "record|sink_right|OA|Receive right|Activity|", "record|left/A|OA|left Watch|Activity|Monitor alarm", "record|left/E|OA|left Alarm|Interaction|left/A|sink_left|data1/Alarm", "record|left/P|OA|left Elapsed|Property|left/A|controls1:Duration|750@controls1:ms", "record|left/C|OA|left Stress|Case|-|left/P=1250@controls1:ms", "record|left/K|OA|left Elapsed limit|Check|left/P|1000@controls1:ms", "record|right/A|OA|right Watch|Activity|Monitor alarm", "record|right/E|OA|right Alarm|Interaction|right/A|sink_right|data1/Alarm", "record|right/P|OA|right Elapsed|Property|right/A|controls1:Duration|750@controls1:ms", "record|right/C|OA|right Stress|Case|-|right/P=1250@controls1:ms", "record|right/K|OA|right Elapsed limit|Check|right/P|1000@controls1:ms", "record|budget|OA|Combined duration|Budget|left/P|right/P|controls1:Duration|2000@controls1:ms", "record|outside|OA|Outside typed receiver|Consumer|left/E|data1/Interface|data1/Operation|data1/Code", "record|global|OA|Unrelated project-wide study|Case|-|left/P=3000@controls1:ms", ]; let expected_initial_live: BTreeMap<_, _> = expected_initial_rows .iter() .map(|line| Record::parse(line).map(|r| (r.id.clone(), r))) .collect::>()?; check!(initial.live == expected_initial_live); write( &root.join("expected-initial.model"), &(expected_initial_rows.join("\n") + "\n"), )?; check!(initial.live.len() == 15); check!(initial.instances["left"].current.values().all(|id| { !initial.instances["right"] .current .values() .any(|other| id == other) })); check!(evaluate(&initial, "budget")? == (1500, true)); save(&initial, &root.join("01-initial"))?; check!(load(&root.join("01-initial"))? == initial); save( &load(&root.join("01-initial"))?, &root.join("01-recompiled"), )?; check!( read(&root.join("01-initial/project.model"))? == read(&root.join("01-recompiled/project.model"))? ); write( &root.join("local-edit.request"), "edit_base|left/P|900@controls1:ms\n", )?; let edited = apply_edit(&initial, &read(&root.join("local-edit.request"))?)?; check!(edited.instances == initial.instances); check!(evaluate(&edited, "budget")? == (1650, true)); save(&edited, &root.join("02-edited"))?; let request = format!( "update|left|{}|controls2|data2|2|P.base=keep_local\n", p1.digest ); write(&root.join("selective-update.request"), &request)?; check!( update( &edited, &request.replace("P.base=keep_local", "unresolved"), p2.clone() ) .is_err() ); check!(update(&edited, &request.replace("|2|", "|1|"), p2.clone()).is_err()); let updated = update( &edited, &read(&root.join("selective-update.request"))?, p2.clone(), )?; check!(evaluate_policy(&initial, "budget", &Policy::Strict)? == (1500, true)); check!(consumer_match_policy(&initial, "outside", &Policy::Strict).is_ok()); check!(evaluate_policy(&updated, "budget", &Policy::Strict).is_err()); check!(consumer_match_policy(&updated, "outside", &Policy::Strict).is_err()); check!(evaluate(&updated, "budget")? == (1650, true)); check!(evaluate_check(&updated, "left/K", None)? == (900, true)); check!(evaluate_check(&updated, "left/K", Some("left/C"))? == (1250, false)); check!(evaluate_check(&updated, "left/K", Some("global"))? == (3000, false)); check!(evaluate_check(&updated, "right/K", Some("right/C"))? == (1250, false)); check!(updated.instances["right"] == edited.instances["right"]); check!(updated.live["right/P"] == edited.live["right/P"]); for id in ["outside", "budget", "global", "sink_left", "sink_right"] { check!(updated.live[id] == edited.live[id]); } for (member, current) in &edited.instances["left"].current { check!(updated.instances["left"].current[member] == *current); } let Body::Property { kind, base, .. } = &updated.live["left/P"].body else { unreachable!() }; check!(kind == &DRef::new("controls2", "Duration")); check!(base == &Literal::new(900, "controls1", "ms")); let Body::Property { base, .. } = &updated.instances["left"].base["P"].body else { unreachable!() }; check!(base == &Literal::new(750, "controls2", "ms")); check!(updated.instances["left"].import == "controls2"); check!( consumer_match(&updated, "outside")? == BTreeMap::from([ ("data1/Alarm".into(), "data2/Alarm".into()), ("data1/Code".into(), "data2/Code".into()), ("data1/Flag".into(), "data2/Flag".into()), ("data1/Interface".into(), "data2/Interface".into()), ("data1/Operation".into(), "data2/Operation".into()) ]) ); save(&updated, &root.join("03-updated"))?; check!(load(&root.join("03-updated"))? == updated); // Independently authored expectations: no materialize()/update() call supplies these rows. let expected_rows = [ "record|left/P|OA|left Elapsed|Property|left/A|controls2:Duration|900@controls1:ms", "record|left/E|OA|left Alarm|Interaction|left/A|sink_left|data2/Alarm", "record|left/C|OA|left Stress|Case|-|left/P=1250@controls2:ms", "record|left/K|OA|left Elapsed limit|Check|left/P|1000@controls2:ms", "record|right/P|OA|right Elapsed|Property|right/A|controls1:Duration|750@controls1:ms", "record|budget|OA|Combined duration|Budget|left/P|right/P|controls1:Duration|2000@controls1:ms", "record|outside|OA|Outside typed receiver|Consumer|left/E|data1/Interface|data1/Operation|data1/Code", ]; for line in expected_rows { let expected = Record::parse(line)?; check!(updated.live[&expected.id] == expected); } write( &root.join("expected-key-records.model"), &(expected_rows.join("\n") + "\n"), )?; // Full independent graph oracle, including every accepted baseline and management map. let mut expected_live = expected_initial_live; for line in expected_rows { let r = Record::parse(line)?; expected_live.insert(r.id.clone(), r); } let expected_mounts = BTreeMap::from([ ( "data1".into(), Mount { import: "controls1".into(), members: BTreeMap::from([ ("Alarm".into(), "data1/Alarm".into()), ("Code".into(), "data1/Code".into()), ("Flag".into(), "data1/Flag".into()), ("Interface".into(), "data1/Interface".into()), ("Operation".into(), "data1/Operation".into()), ]), }, ), ( "data2".into(), Mount { import: "controls2".into(), members: BTreeMap::from([ ("Alarm".into(), "data2/Alarm".into()), ("Code".into(), "data2/Code".into()), ("Flag".into(), "data2/Flag".into()), ("Interface".into(), "data2/Interface".into()), ("Operation".into(), "data2/Operation".into()), ]), }, ), ]); let mut expected_instances = BTreeMap::new(); for (prefix, import, mount, sink) in [ ("left", "controls2", "data2", "sink_left"), ("right", "controls1", "data1", "sink_right"), ] { let original: BTreeMap = ["A", "C", "E", "K", "P"] .into_iter() .map(|m| (m.into(), format!("{prefix}/{m}"))) .collect(); let mut base: BTreeMap = original .iter() .map(|(m, id)| (m.clone(), expected_live[id].clone())) .collect(); if prefix == "left" { base.insert("P".into(), Record::parse("record|left/P|OA|left Elapsed|Property|left/A|controls2:Duration|750@controls2:ms")?); } expected_instances.insert( prefix.into(), Instance { import: import.into(), mount: mount.into(), sink: sink.into(), prefix: prefix.into(), current: original .iter() .map(|(m, id)| (m.clone(), Some(id.clone()))) .collect(), lineage: original .values() .map(|id| (id.clone(), id.clone())) .collect(), original, base, }, ); } let expected_full = Document { identity: "Alpha".into(), revision: 3, imports: BTreeMap::from([ ("controls1".into(), p1.clone()), ("controls2".into(), p2.clone()), ]), mounts: expected_mounts, instances: expected_instances, live: expected_live, receipts: vec![ "create-two-instances".into(), "edit_base|left/P|900@controls1:ms".into(), request.trim().into(), ], }; check!(updated == expected_full); save(&expected_full, &root.join("expected-full-updated"))?; // Unchanged exact identity remains a stricter relation than compatibility. check!(updated.imports["controls1"].digest != updated.imports["controls2"].digest); check!(DRef::new("controls1", "Duration") != DRef::new("controls2", "Duration")); check!(updated.mounts["data1"].members["Alarm"] != updated.mounts["data2"].members["Alarm"]); check!(update(&edited, &request, p3.clone()).is_err()); let mut forged = updated.clone(); forged .instances .get_mut("left") .unwrap() .base .get_mut("P") .unwrap() .name = "Forged history".into(); check!(admit(&forged).is_err()); let mut forged = updated.clone(); forged.imports.get_mut("controls1").unwrap().raw.push(' '); check!(admit(&forged).is_err()); let mut forged_parsed = updated.clone(); forged_parsed .imports .get_mut("controls1") .unwrap() .definitions .get_mut("Alarm") .unwrap() .layer = "SA".into(); check!(admit(&forged_parsed).is_err()); let mut label_collision = updated.clone(); label_collision.imports.insert( "conflicting_version".into(), Package::parse( p1.raw .replace("Initial documentation", "Another revision claiming 1.0.0"), )?, ); check!(admit(&label_collision).is_err()); let mut collision = updated.clone(); collision .instances .get_mut("left") .unwrap() .current .insert("P".into(), Some("right/P".into())); check!(admit(&collision).is_err()); let mut missing = updated.clone(); missing.imports.remove("controls1"); check!(admit(&missing).is_err()); let mut other_local_edits = edited.clone(); let property = other_local_edits.live.get_mut("left/P").unwrap(); property.name = "Local measurement name".into(); let Body::Property { subject, .. } = &mut property.body else { unreachable!() }; *subject = "sink_left".into(); let twice_edited = update(&other_local_edits, &request, p2.clone())?; check!(twice_edited.live["left/P"].name == "Local measurement name"); let Body::Property { subject, .. } = &twice_edited.live["left/P"].body else { unreachable!() }; check!(subject == "sink_left"); let mut extended = edited.clone(); extended.live.insert( "local_extra".into(), Record { id: "local_extra".into(), layer: "OA".into(), name: "left Watch".into(), body: Body::Activity { description: "Independent extension".into(), }, }, ); let extended_update = update(&extended, &request, p2.clone())?; check!(extended_update.live["local_extra"] == extended.live["local_extra"]); let mut dangling = edited.clone(); dangling.live.remove("left/E"); dangling .instances .get_mut("left") .unwrap() .current .insert("E".into(), None); check!(admit(&dangling).is_err()); // Explicit reidentify changes live references/current map/lineage, never base or foreign origins. let mut reidentified = edited.clone(); let mut moved = reidentified.live.remove("left/A").unwrap(); moved.remap_live("left/A", "left/A2"); reidentified.live.insert(moved.id.clone(), moved); for record in reidentified.live.values_mut() { record.remap_live("left/A", "left/A2"); } let i = reidentified.instances.get_mut("left").unwrap(); i.current.insert("A".into(), Some("left/A2".into())); i.lineage.insert("left/A".into(), "left/A2".into()); check!(admit(&reidentified).is_ok()); check!(reidentified.instances["left"].base == edited.instances["left"].base); check!(reidentified.imports == edited.imports); let mut reused = reidentified.clone(); reused.live.insert( "left/A".into(), Record { id: "left/A".into(), layer: "OA".into(), name: "New object".into(), body: Body::Activity { description: String::new(), }, }, ); check!(admit(&reused).is_err()); save(&reidentified, &root.join("04-reidentified"))?; check!(load(&root.join("04-reidentified"))? == reidentified); let reupdated = update(&reidentified, &request, p2.clone())?; check!(reupdated.live.contains_key("left/A2") && !reupdated.live.contains_key("left/A")); // A deleted member remains reserved; no implicit resurrection or name adoption. let mut deleted = edited.clone(); deleted.live.remove("left/K"); deleted .instances .get_mut("left") .unwrap() .current .insert("K".into(), None); check!(admit(&deleted).is_ok()); check!(update(&deleted, &request, p2.clone()).is_err()); deleted.live.insert( "left/K".into(), Record { id: "left/K".into(), layer: "OA".into(), name: "Same-looking new check".into(), body: Body::Check { property: "right/P".into(), limit: Literal::new(1000, "controls1", "ms"), }, }, ); check!(admit(&deleted).is_err()); // Subjectless C/K are included only by explicit selection; G is never inverse-pulled. check!(analysis_scope(&["P"], &[], &[], &[])? == BTreeSet::from(["P".into()])); check!( analysis_scope(&["P"], &["K"], &["C"], &[])? == BTreeSet::from(["P".into(), "K".into(), "C".into()]) ); check!(analysis_scope(&[], &[], &["G"], &[]).is_err()); check!(analysis_scope(&[], &[], &["G"], &["Q"])? == BTreeSet::from(["G".into(), "P".into()])); // Layer transformation has independent provenance and mutability, not implicit compatibility. let sa = derivative(&p2); check!(!sa.mount && sa.layer == "SA" && sa.origin_pin == p2.digest); check!(sa.records.len() == 5 && sa.origin_map.len() == 5); let mut sa_raw = String::from("package|ControlPatternsSA|1.0.1\ndescription|Explicit SA counterpart\n"); for d in sa.records.values() { sa_raw += &format!( "def|{}|{}|{}|{}|{}\n", d.member, d.class, d.layer, d.fields.join(","), d.refs.join(",") ); } let sa_package = Package::parse(sa_raw)?; let pinned = pinned_counterpart(&p2, &sa_package, &sa.origin_map)?; check!( pinned.mount && pinned.records == sa.records && pinned.target_pin == Some(sa_package.digest.clone()) ); check!(!equivalent(&p2, "Alarm", &sa_package, "SA/Alarm")); let mut incomplete = sa.origin_map.clone(); incomplete.remove("Code"); check!(pinned_counterpart(&p2, &sa_package, &incomplete).is_err()); let mut refined = sa.clone(); refined.records.get_mut("SA/Code").unwrap().fields = vec!["minimum=1;maximum=2".into()]; let refined_package = Package::parse(sa_package.raw.replace("maximum=1", "maximum=2"))?; check!(pinned_counterpart(&p2, &refined_package, &sa.origin_map).is_err()); check!(derivative(&p2).records == sa.records); // Explicit reverse BindPinned may reuse the original unchanged OA contract. check!(derivative(&p2).records != refined.records); // Reverse transition of an edited derivative must not mutate the original mount. let pinned_architecture = target_architecture(&pinned)?; let local_architecture = target_architecture(&sa)?; check!(pinned_architecture.len() == 5 && local_architecture.len() == 5); check!( pinned_architecture["sa/alarm"] == TargetRecord::FunctionalExchange { source: "sa/watch".into(), target: "sa/receive".into(), source_port: "sa/watch_out".into(), target_port: "sa/receive_in".into(), item: "sa_mount/SA/Alarm".into() } ); check!( local_architecture["sa/alarm"] == TargetRecord::FunctionalExchange { source: "sa/watch".into(), target: "sa/receive".into(), source_port: "sa/watch_out".into(), target_port: "sa/receive_in".into(), item: "SA/Alarm".into() } ); let mut wrong_layer = sa.clone(); wrong_layer.records.get_mut("SA/Alarm").unwrap().layer = "OA".into(); check!(target_architecture(&wrong_layer).is_err()); check!(sa == derivative(&p2)); // Original source/package revisions have not mutated the captured derivative. check!(derivative(&p3).records != sa.records); let mut illegal = p2.clone(); illegal.definitions.get_mut("Alarm").unwrap().layer = "SA".into(); check!(!equivalent(&p2, "Alarm", &illegal, "Alarm")); write( &root.join("oa-sa-transition.model"), &format!( "pinned-counterpart={pinned:#?}\npinned-architecture={pinned_architecture:#?}\nlocal-derivative={sa:#?}\nlocal-architecture={local_architecture:#?}\nrefined-derivative={refined:#?}\n" ), )?; // Checked identity bridges are scoped direct witnesses, not unverified flags or dimension casts. let bridge = |a: &Package, am: &str, b: &Package, bm: &str| -> Result { if equivalent(a, am, b, bm) { Ok(format!( "checked-same-origin|{}|{am}|{}|{bm}", a.digest, b.digest )) } else { Err("bridge proof failed".into()) } }; check!(bridge(&p1, "Duration", &p2, "Duration").is_ok()); check!(bridge(&p1, "Interface", &p2, "Interface").is_ok()); check!(bridge(&p1, "Energy", &p1, "Torque").is_err()); check!(bridge(&p1, "Interface", &p3, "Interface").is_err()); let witnesses = BTreeSet::from([ pair( &format!("{}:Duration", p1.digest), &format!("{}:Duration", p2.digest), ), pair( &format!("{}:Interface", p1.digest), &format!("{}:Interface", p2.digest), ), ]); let explicit_policy = Policy::Bridges(witnesses); check!(evaluate_policy(&updated, "budget", &explicit_policy)? == (1650, true)); check!(consumer_match_policy(&updated, "outside", &explicit_policy).is_ok()); check!(evaluate_policy(&updated, "budget", &Policy::Bridges(BTreeSet::new())).is_err()); check!(consumer_match_policy(&updated, "outside", &Policy::Bridges(BTreeSet::new())).is_err()); // Qualified layered definitions have the same compatibility/layer obligations without materialized IDs. check!(policy_matches( &p1, "Interface", &p2, "Interface", &Policy::SameOrigin )); check!(!policy_matches( &p1, "Interface", &p2, "Interface", &Policy::Strict )); check!(p2.definitions["Alarm"].layer != "SA"); check!(sa_package.definitions["SA/Alarm"].layer == "SA"); let bridge_text = format!( "{}\n{}\n", bridge(&p1, "Duration", &p2, "Duration")?, bridge(&p1, "Interface", &p2, "Interface")? ); write(&root.join("explicit-bridges.model"), &bridge_text)?; // Stable vocabulary separates pattern bytes from definition provenance, but vocabulary changes still need the same decision. let vocabulary_pin = p1.digest.clone(); let pattern1 = ("PatternRevision1", vocabulary_pin.clone()); let pattern2 = ("PatternRevision2", vocabulary_pin.clone()); check!(pattern1.0 != pattern2.0 && pattern1.1 == pattern2.1); check!(pattern1.1 != p3.digest); let results = format!( "# Finite-model results\n\nAssertions passed: {checks}\n\nInitial budget: 1500 ms, satisfied.\nAfter one local base edit: 1650 ms, satisfied.\nAfter selected cosmetic update: 1650 ms, satisfied; exact pins differ.\nOutside budget/consumer/global case: exact records unchanged.\nUpdated left baseline: 750 controls2:ms; current: 900 controls1:ms; declared kind controls2:Duration.\nRight instance/base/map: exact original.\nContract path projection: data1/Code -> data2/Code and data1/Operation -> data2/Operation.\nChanged field cardinality: selective candidate rejected.\nStrict revision identity: old/new refs unequal.\nSame-origin typed compatibility: cosmetic revision accepted; Energy/Torque, other origin, changed contract rejected.\nBridge alternative: 2 explicit validated direct witnesses; changed contracts rejected.\nStable vocabulary alternative: exact common pin survives pattern change; vocabulary change remains unresolved without compatibility/migration.\nSubjectless explicit C+K selected; unrelated G omitted; selected G requires Q boundary.\nOA/SA: explicit pinned counterpart or independent local derivative; refined reverse counterpart fails exact transformed contract.\n\nD1: {}\nD2: {}\nD3: {}\n\nThis dialect uses opaque symbolic identities, a restricted AST, one package per import and scalar integer-millisecond arithmetic. It is not Studio source, a full package dependency solver, production UUID allocation, complete data/operation/transition admission, REST or native acceptance.\n", p1.digest, p2.digest, p3.digest ); write(&root.join("RESULTS.md"), &results)?; write(&root.join("package-D1.library"), &p1.raw)?; write(&root.join("package-D2.library"), &p2.raw)?; write(&root.join("package-D3.library"), &p3.raw)?; write(&root.join("package-SA.library"), &sa_package.raw)?; println!( "{checks} assertions passed\nD1={}\nD2={}\nD3={}", p1.digest, p2.digest, p3.digest ); Ok(()) }