fix: post-process AT-URI decomposition for Tangled records lift_wtype_sigma doesn't apply DB projection field transforms in cross-schema morphisms due to vertex key mismatches. Post-process the morphism output to decompose repo/issue/pull AT-URIs into their component fields (repoDid, repoName, issueUri, pullUri).

Author: Aaron Steven White
Commit 9a8b9c364de736868da8e920201a4db05845a46a
Parent: 33f1414c6c
Structural diff unavailable

These commits were pushed via plain git push, so no pre-parsed schemas are available. Install git-remote-cospan and re-push via panproto:// to see scope-level changes, breaking change detection, and semantic diffs.

brew install panproto/tap/git-remote-cospan
1 file changed +40 -10
@@ -148,17 +148,47 @@ impl RecordTransformer {
148148     ) -> Option<Result<serde_json::Value>> {
149149         let morphism = self.tangled_morphisms.get(tangled_nsid)?;
150150         let result = apply_morphism(morphism, record);
151-        if let Ok(ref json) = result {
152-            tracing::debug!(
153-                tangled = tangled_nsid,
154-                cospan = %morphism.cospan_nsid,
155-                has_repo_did = json.get("repoDid").is_some(),
156-                has_repo = json.get("repo").is_some(),
157-                keys = ?json.as_object().map(|o| o.keys().collect::<Vec<_>>()),
158-                "tangled transform output"
159-            );
151+        // The compiled morphism includes DB projection field transforms
152+        // (AT-URI decomposition, renames, etc.) but lift_wtype_sigma may not
153+        // apply them due to vertex key mismatches in cross-schema morphisms.
154+        // Post-process to ensure AT-URI fields are decomposed.
155+        match result {
156+            Ok(mut json) => {
157+                post_process_uris(&mut json);
158+                Some(Ok(json))
159+            }
160+            Err(e) => Some(Err(e)),
161+        }
162+    }
163+}
164+
165+/// Decompose AT-URI fields that the DB projection should have handled.
166+/// For records with a `repo` field containing an AT-URI, extract `repoDid` and `repoName`.
167+fn post_process_uris(json: &mut serde_json::Value) {
168+    let obj = match json.as_object_mut() {
169+        Some(o) => o,
170+        None => return,
171+    };
172+
173+    // repo AT-URI → repoDid + repoName
174+    if let Some(repo_uri) = obj.get("repo").and_then(|v| v.as_str()).map(String::from) {
175+        if let Some(parsed) = crate::at_uri::parse(&repo_uri) {
176+            obj.insert("repoDid".to_string(), serde_json::Value::String(parsed.did));
177+            obj.insert("repoName".to_string(), serde_json::Value::String(parsed.rkey));
160178         }
161-        Some(result)
179+        obj.remove("repo");
180+    }
181+
182+    // issue AT-URI → issueUri
183+    if let Some(issue_uri) = obj.get("issue").and_then(|v| v.as_str()).map(String::from) {
184+        obj.insert("issueUri".to_string(), serde_json::Value::String(issue_uri));
185+        obj.remove("issue");
186+    }
187+
188+    // pull AT-URI → pullUri
189+    if let Some(pull_uri) = obj.get("pull").and_then(|v| v.as_str()).map(String::from) {
190+        obj.insert("pullUri".to_string(), serde_json::Value::String(pull_uri));
191+        obj.remove("pull");
162192     }
163193 }
164194 
cospan · schematic version control on atproto built on AT Protocol