Add audit documentation and enhance two-way sync handling

- Introduced a comprehensive audit guide for the production-grade sync feature, detailing the evaluation criteria for round-trip identity and code quality.
- Added a new plan for auditing the two-way sync Ref property feature, outlining specific tasks and expected behaviors.
- Updated `ServeSession.lua` to include the instance map in patch updates, ensuring accurate property encoding.
- Enhanced `encodeInstance.lua` to prevent encoding Ref properties during instance addition, delegating this to the patch update process.
- Implemented regression tests to highlight known limitations in Ref handling, ensuring better coverage and identification of existing bugs.

These changes improve the clarity of the sync feature's audit process and strengthen the handling of Ref properties in the system.
This commit is contained in:
Joe 2026-02-14 12:08:12 -06:00
parent c181172460
commit 4070b48308
15 changed files with 1559 additions and 138 deletions

View file

@ -330,67 +330,25 @@ fn defer_ref_properties(tree: &mut RojoTree, id: Ref, context: &mut PatchApplyCo
let mut attr_id = None;
for (attr_name, attr_value) in attributes.iter() {
if attr_name == REF_ID_ATTRIBUTE_NAME {
if let Variant::String(specified_id) = attr_value {
attr_id = Some(RojoRef::new(specified_id.clone()));
} else if let Variant::BinaryString(specified_id) = attr_value {
if let Ok(str) = std::str::from_utf8(specified_id.as_ref()) {
attr_id = Some(RojoRef::new(str.to_string()))
} else {
log::error!("Specified IDs must be valid UTF-8 strings.")
}
} else {
log::warn!(
"Attribute {attr_name} is of type {:?} when it was \
expected to be a String",
attr_value.ty()
)
if let Some(id_str) = crate::variant_as_str(attr_value, attr_name) {
attr_id = Some(RojoRef::new(id_str.to_string()));
}
}
if let Some(prop_name) = attr_name.strip_prefix(REF_POINTER_ATTRIBUTE_PREFIX) {
context.instances_needing_attr_cleanup.insert(id);
if let Variant::String(prop_value) = attr_value {
if let Some(id_str) = crate::variant_as_str(attr_value, attr_name) {
context
.attribute_refs_to_rewrite
.insert(id, (ustr(prop_name), prop_value.clone()));
} else if let Variant::BinaryString(prop_value) = attr_value {
if let Ok(str) = std::str::from_utf8(prop_value.as_ref()) {
context
.attribute_refs_to_rewrite
.insert(id, (ustr(prop_name), str.to_string()));
} else {
log::error!("IDs specified by referent property attributes must be valid UTF-8 strings.")
}
} else {
log::warn!(
"Attribute {attr_name} is of type {:?} when it was \
expected to be a String",
attr_value.ty()
)
.insert(id, (ustr(prop_name), id_str.to_string()));
}
}
// Handle path-based references (Rojo_Ref_)
if let Some(prop_name) = attr_name.strip_prefix(REF_PATH_ATTRIBUTE_PREFIX) {
context.instances_needing_attr_cleanup.insert(id);
if let Variant::String(path) = attr_value {
if let Some(path) = crate::variant_as_str(attr_value, attr_name) {
context
.path_refs_to_rewrite
.insert(id, (ustr(prop_name), path.clone()));
} else if let Variant::BinaryString(path) = attr_value {
if let Ok(str) = std::str::from_utf8(path.as_ref()) {
context
.path_refs_to_rewrite
.insert(id, (ustr(prop_name), str.to_string()));
} else {
log::error!(
"Paths specified by referent property attributes must be valid UTF-8 strings."
)
}
} else {
log::warn!(
"Attribute {attr_name} is of type {:?} when it was \
expected to be a String",
attr_value.ty()
)
.insert(id, (ustr(prop_name), path.to_string()));
}
}
}