mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-20 10:06:54 +03:00
Capture original review images and bind the measured inventory
Support static WebP and JPEG without conversion-cache evidence. Bind the measured spec centrally, require complete semantic component previews, and present the initial kit before automatic gate-driven repairs. AI assistance: implemented and validated with OpenAI Codex.
This commit is contained in:
@@ -110,6 +110,21 @@ pub fn freeze(project: &Path, input: &Value) -> Result<(Value, BTreeMap<String,
|
||||
}
|
||||
let mut files = BTreeMap::new();
|
||||
let mut comp_files = BTreeMap::new();
|
||||
// The component inventory is measured against this spec. Bind it centrally
|
||||
// rather than requiring every component author to repeat this dependency.
|
||||
if input["stage"] == "components" {
|
||||
let spec_path = ".impeccable/build/spec.json";
|
||||
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())?;
|
||||
for region in spec["regions"].as_array().ok_or("measured spec needs 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"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
view(&mut packet["comp"], project, &mut files, &mut comp_files)?;
|
||||
let mut ids = BTreeSet::new();
|
||||
let components = packet["components"]
|
||||
|
||||
@@ -471,3 +471,21 @@ fn verify_requires_native_approval_and_current_manifest_and_dependencies() {
|
||||
fs::write(f.project.join("shared.css"), b"changed after approval").unwrap();
|
||||
assert!(super::verify::approved(&f.store,&f.project,"review.json").unwrap_err().contains("changed"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn measured_inventory_is_bound_without_repeated_author_dependencies() {
|
||||
let f = Fixture::new();
|
||||
fs::create_dir_all(f.project.join(".impeccable/build")).unwrap();
|
||||
let path = f.project.join(".impeccable/build/spec.json");
|
||||
fs::write(&path, br#"{"regions":[{"id":"art","kind":"plate"},{"id":"control","kind":"control"}]}"#).unwrap();
|
||||
let mut input = f.manifest(); input["stage"] = json!("components");
|
||||
let dir = store::prepare(&f.store, &f.project, &input).unwrap();
|
||||
let state = store::read(&dir.join("current.json")).unwrap();
|
||||
assert!(state["sources"][".impeccable/build/spec.json"].is_string());
|
||||
let mut missing = input.clone(); missing["components"].as_array_mut().unwrap().pop();
|
||||
assert!(store::prepare(&f.store, &f.project, &missing).unwrap_err().contains("omitted measured region"));
|
||||
let mut flattened = input; flattened["components"][1]["preview"] = json!({"kind":"image","path":"art.png"});
|
||||
assert!(store::prepare(&f.store, &f.project, &flattened).unwrap_err().contains("rendered code preview"));
|
||||
fs::write(path, br#"{"regions":[]}"#).unwrap();
|
||||
assert!(store::sources_current(&state).is_err());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user