Rust checks / check (ubuntu-latest) (push) Canceled after 0s
Rust checks / check (windows-latest) (push) Canceled after 0s
Preserve current core, source, REST, desktop, recovery, documentation and validation work, including AGENTS.md and the development summary. This is a work-in-progress checkpoint: the new compact palette has outstanding compilation errors and native acceptance; earlier passing gates retain their documented scope.
147 lines
5.5 KiB
Rust
147 lines
5.5 KiB
Rust
//! Independent exact native lesson oracle, compiled against existing core libraries.
|
|
//! Usage: CHECKER oa|review|fold|state-rename NATIVE_ENTRY BEFORE_REVIEW_ENTRY OUTPUT_DIRECTORY
|
|
#[path = "../examples/release1/model.rs"]
|
|
mod teaching;
|
|
use oa_core::{source_files, source_project::*, transitions::*, *};
|
|
use std::{fs, path::Path};
|
|
|
|
fn disk(entry: &Path) -> CompiledSourceProject {
|
|
let read = source_files::load_project(entry, ProjectLimits::default()).unwrap();
|
|
assert!(
|
|
read.diagnostics
|
|
.iter()
|
|
.all(|diagnostic| diagnostic.diagnostic.severity != validation::Severity::Error),
|
|
"{:?}",
|
|
read.diagnostics
|
|
);
|
|
let raw = read.reachable_bundle();
|
|
let compiled = compile_bundle(&raw, ProjectLimits::default()).unwrap();
|
|
assert_eq!(
|
|
raw, compiled.bundle,
|
|
"Use a checker built for the source profile being measured; migration or identity stabilization must not normalize the native bytes."
|
|
);
|
|
compiled
|
|
}
|
|
fn compare(expected: &CompiledSourceProject, actual: &CompiledSourceProject, label: &str) {
|
|
assert_eq!(
|
|
expected.decoded.project, actual.decoded.project,
|
|
"{label}: full model differs; no metadata/identity exclusions are allowed"
|
|
);
|
|
assert_eq!(
|
|
expected.bundle.entry, actual.bundle.entry,
|
|
"{label}: entry differs"
|
|
);
|
|
assert_eq!(
|
|
expected.bundle.files.keys().collect::<Vec<_>>(),
|
|
actual.bundle.files.keys().collect::<Vec<_>>(),
|
|
"{label}: module set differs"
|
|
);
|
|
for (name, text) in &expected.bundle.files {
|
|
assert_eq!(
|
|
text, &actual.bundle.files[name],
|
|
"{label}: exact source differs in {name}"
|
|
);
|
|
}
|
|
}
|
|
fn main() {
|
|
let args: Vec<_> = std::env::args().collect();
|
|
assert_eq!(
|
|
args.len(),
|
|
5,
|
|
"usage: CHECKER oa|review|fold|state-rename NATIVE_ENTRY BEFORE_REVIEW_ENTRY OUTPUT_DIRECTORY"
|
|
);
|
|
assert!(matches!(
|
|
args[1].as_str(),
|
|
"oa" | "review" | "fold" | "state-rename"
|
|
));
|
|
let lesson = teaching::build();
|
|
assert_eq!(lesson.before_transition.id, lesson.project.id);
|
|
assert!(!lesson.request.sources.is_empty());
|
|
let original = compile_bundle(
|
|
&teaching::checked_bundle(&lesson.project),
|
|
ProjectLimits::default(),
|
|
)
|
|
.unwrap();
|
|
let source = teaching::id("oa_confirm");
|
|
let target = teaching::id("sa_confirm");
|
|
let mut renamed = lesson.project.elements[&source].clone();
|
|
renamed.name = "Confirm stable pressure".into();
|
|
let renamed_model =
|
|
execute_batch(&lesson.project, &[Command::EditElement(source, renamed)]).unwrap();
|
|
let before = update_bundle(&original, &renamed_model, ProjectLimits::default()).unwrap();
|
|
compare(
|
|
&before,
|
|
&disk(Path::new(&args[3])),
|
|
"preserved OA rename baseline",
|
|
);
|
|
let mut transition = TransitionRequest::new(TransitionDirection::OaToSa, vec![source]);
|
|
transition.fields.clear();
|
|
transition.mappings.push(TransitionMapping {
|
|
source,
|
|
target: Some(target),
|
|
target_kind: None,
|
|
});
|
|
let mut request = SemanticTransitionRequest::new(transition);
|
|
request.reviews.push(SemanticReviewRequest {
|
|
source,
|
|
resolutions: vec![FacetResolution {
|
|
facet: FacetSelector::Header(HeaderFacet::Name),
|
|
decision: SemanticDecision::TakeSource,
|
|
}],
|
|
reset: vec![],
|
|
});
|
|
let plan = plan_semantic_transition(&before.decoded.project, request).unwrap();
|
|
assert!(plan.conflicts.is_empty(), "{:?}", plan.conflicts);
|
|
let reviewed = apply_semantic_transition(&before.decoded.project, &plan).unwrap();
|
|
let after = update_bundle(&before, &reviewed, ProjectLimits::default()).unwrap();
|
|
let mut state_model = reviewed.clone();
|
|
if args[1] == "fold" {
|
|
let diagram = state_model
|
|
.diagrams
|
|
.get_mut(&teaching::id("sa_state_view"))
|
|
.unwrap();
|
|
let matching: Vec<_> = diagram
|
|
.nodes
|
|
.values_mut()
|
|
.filter(|node| node.element == teaching::id("sa_monitor_region"))
|
|
.collect();
|
|
assert_eq!(matching.len(), 1);
|
|
for node in matching {
|
|
assert!(!node.collapsed);
|
|
node.collapsed = true;
|
|
}
|
|
} else if args[1] == "state-rename" {
|
|
let work = state_model
|
|
.elements
|
|
.get_mut(&teaching::id("sa_assess"))
|
|
.unwrap();
|
|
assert_eq!(work.name, "Assess pressure alarm");
|
|
work.name = "Assess incoming pressure alarm".into();
|
|
}
|
|
let state_model = execute_batch(&reviewed, &[Command::Replace(state_model)]).unwrap();
|
|
let state_after = update_bundle(&after, &state_model, ProjectLimits::default()).unwrap();
|
|
let expected = match args[1].as_str() {
|
|
"oa" => &before,
|
|
"review" => &after,
|
|
_ => &state_after,
|
|
};
|
|
let output = Path::new(&args[4]);
|
|
fs::create_dir_all(output).unwrap();
|
|
fs::write(
|
|
output.join("expected-model.json"),
|
|
serde_json::to_string_pretty(&expected.decoded.project).unwrap(),
|
|
)
|
|
.unwrap();
|
|
fs::write(
|
|
output.join("expected-source-bundle.json"),
|
|
serde_json::to_string_pretty(&expected.bundle).unwrap(),
|
|
)
|
|
.unwrap();
|
|
compare(expected, &disk(Path::new(&args[2])), "native result");
|
|
println!(
|
|
"PASS {}: exact full model and {} source files; preserved OA rename baseline verified; no identity or metadata normalization",
|
|
args[1],
|
|
expected.bundle.files.len()
|
|
);
|
|
}
|