mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-21 10:36:27 +03:00
Report component inventory failures together
Collect independent missing-region and rendered-code-preview errors before native capture so repairs do not require one model turn per omitted region. Preserve all rejection rules. Refresh the embedded review bundle from the unchanged source with pinned Bun 1.3.13. AI-assisted implementation and validation by Codex under maintainer direction. Validation: cargo test --workspace; release build; IMPECCABLE_BIN=target/release/impeccable bun run test; bun run build.
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -121,13 +121,21 @@ pub fn freeze(project: &Path, input: &Value) -> Result<(Value, BTreeMap<String,
|
||||
comp_files.insert(spec_path.into(), pin(project, spec_path, &mut files)?);
|
||||
let spec: Value = serde_json::from_slice(&files[spec_path]).map_err(|e| e.to_string())?;
|
||||
measured_regions = spec["regions"].as_array().ok_or("measured spec needs regions")?.clone();
|
||||
// These checks are independent. Report the complete inventory repair in
|
||||
// one response before any browser work, without publishing partial proof.
|
||||
let mut errors = Vec::new();
|
||||
for region in &measured_regions {
|
||||
let component = input["components"].as_array().and_then(|items| items.iter().find(|c| c["id"] == region["id"]))
|
||||
.ok_or_else(|| format!("component review omitted measured region {}", region["id"]))?;
|
||||
if matches!(region["kind"].as_str(), Some("text" | "control")) && component["preview"]["kind"] != "page" {
|
||||
return Err(format!("semantic region {} requires a rendered code preview", region["id"]));
|
||||
match input["components"].as_array().and_then(|items| items.iter().find(|c| c["id"] == region["id"])) {
|
||||
None => errors.push(format!("component review omitted measured region {}", region["id"])),
|
||||
Some(component) if matches!(region["kind"].as_str(), Some("text" | "control")) && component["preview"]["kind"] != "page" => {
|
||||
errors.push(format!("semantic region {} requires a rendered code preview", region["id"]));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if !errors.is_empty() {
|
||||
return Err(errors.join("\n"));
|
||||
}
|
||||
}
|
||||
|
||||
view(&mut packet["comp"], project, &mut files, &mut comp_files)?;
|
||||
@@ -170,8 +178,9 @@ pub fn freeze(project: &Path, input: &Value) -> Result<(Value, BTreeMap<String,
|
||||
if let Some(group) = input["components"].as_array().and_then(|cs| cs.iter().find(|c| c["id"] == region["id"]))
|
||||
.and_then(|c| c.get("reviewGroup")) { region["reviewGroup"] = group.clone(); }
|
||||
}
|
||||
if let Some((id, message)) = impeccable_comp::review_groups::issues(&measured_regions).first() {
|
||||
return Err(format!("component {id}: {message}"));
|
||||
let group_issues = impeccable_comp::review_groups::issues(&measured_regions);
|
||||
if !group_issues.is_empty() {
|
||||
return Err(group_issues.iter().map(|(id, message)| format!("component {id}: {message}")).collect::<Vec<_>>().join("\n"));
|
||||
}
|
||||
let mut ids = BTreeSet::new();
|
||||
let components = packet["components"]
|
||||
|
||||
@@ -709,3 +709,18 @@ fn component_review_refuses_groups_that_mix_measured_roles() {
|
||||
fs::write(&path, spec.to_string()).unwrap();
|
||||
assert_eq!(manifest::freeze(&f.project,&input).unwrap().0["components"].as_array().unwrap().len(),3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn measured_inventory_reports_all_independent_failures_before_capture() {
|
||||
let f = Fixture::new();
|
||||
fs::create_dir_all(f.project.join(".impeccable/build")).unwrap();
|
||||
fs::write(f.project.join(".impeccable/build/spec.json"), br#"{"regions":[{"id":"missing-one","kind":"plate"},{"id":"control","kind":"control"},{"id":"missing-two","kind":"text"}]}"#).unwrap();
|
||||
let mut input = f.manifest();
|
||||
input["stage"] = json!("components");
|
||||
input["components"][1]["preview"] = json!({"kind":"image","path":"art.png"});
|
||||
let error = store::prepare(&f.store, &f.project, &input).unwrap_err();
|
||||
assert!(error.contains("missing-one"));
|
||||
assert!(error.contains("missing-two"));
|
||||
assert!(error.contains("semantic region \"control\" requires a rendered code preview"));
|
||||
assert!(!f.store.exists(), "invalid inventory must not publish a review");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user