diff --git a/bobbin/crates/bobbin-sim/src/workloads/cancel_mid_hydration.rs b/bobbin/crates/bobbin-sim/src/workloads/cancel_mid_hydration.rs index d112ac518..d53ec9071 100644 --- a/bobbin/crates/bobbin-sim/src/workloads/cancel_mid_hydration.rs +++ b/bobbin/crates/bobbin-sim/src/workloads/cancel_mid_hydration.rs @@ -184,13 +184,19 @@ fn build_frames(count: usize) -> Vec { "live": false, "did": star_did, "rev": format_tid(i), - "collection": "sh.tangled.feed.star", + "collection": "org.tangled.feed.star", "rkey": format_rkey(i + 1_000_000), "action": "create", "record": { - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subject": format!("at://{target_owner}/{REPO_COLLECTION}/{target_rkey}") + "subject": { + "$type": "org.tangled.feed.star#record", + "record": { + "uri": format!("at://{target_owner}/{REPO_COLLECTION}/{target_rkey}"), + "cid": "bafyreieqygohnz2zqyvtvktbjpvhutphobcmbsnt4q5lc36ri7vpcmoz4i" + } + } } } }) diff --git a/bobbin/crates/bobbin-sim/src/workloads/slingshot_flap.rs b/bobbin/crates/bobbin-sim/src/workloads/slingshot_flap.rs index 135621582..2605a90f5 100644 --- a/bobbin/crates/bobbin-sim/src/workloads/slingshot_flap.rs +++ b/bobbin/crates/bobbin-sim/src/workloads/slingshot_flap.rs @@ -192,13 +192,19 @@ fn build_frame_script(cfg: &SlingshotFlapConfig, started_unix: UnixMicros) -> Ve "live": false, "did": star_did, "rev": format_tid(i), - "collection": "sh.tangled.feed.star", + "collection": "org.tangled.feed.star", "rkey": format_rkey(i + 1_000_000), "action": "create", "record": { - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subject": format!("at://{target_owner}/{REPO_COLLECTION}/{target_rkey}") + "subject": { + "$type": "org.tangled.feed.star#record", + "record": { + "uri": format!("at://{target_owner}/{REPO_COLLECTION}/{target_rkey}"), + "cid": "bafyreieqygohnz2zqyvtvktbjpvhutphobcmbsnt4q5lc36ri7vpcmoz4i" + } + } } } }) diff --git a/bobbin/crates/bobbin-sim/tests/warming_buffer.rs b/bobbin/crates/bobbin-sim/tests/warming_buffer.rs index fd6dd2d5c..771d6a9c4 100644 --- a/bobbin/crates/bobbin-sim/tests/warming_buffer.rs +++ b/bobbin/crates/bobbin-sim/tests/warming_buffer.rs @@ -181,8 +181,8 @@ fn warming_to_ready_promote_drains_residual_via_parallel_slingshot_wave() { assert_eq!( report.edge_count, stars * 2 + 3, - "each drained star contributes a primary edge plus a sh.tangled.feed.star.by mirror edge; \ - the promoter repo adds one, and the (sh.tangled.feed.star, Global) and \ + "each drained star contributes a primary edge plus a org.tangled.feed.star.by mirror edge; \ + the promoter repo adds one, and the (org.tangled.feed.star, Global) and \ (sh.tangled.repo, Global) feed keys add one each. got {} for {stars} stars", report.edge_count, ); diff --git a/bobbin/crates/edge-index/benches/distinct_authors.rs b/bobbin/crates/edge-index/benches/distinct_authors.rs index 4e81eac85..d2ac347ee 100644 --- a/bobbin/crates/edge-index/benches/distinct_authors.rs +++ b/bobbin/crates/edge-index/benches/distinct_authors.rs @@ -30,13 +30,13 @@ fn did(value: &str) -> Did { fn populated_store(edges: usize, author_for: impl Fn(usize) -> usize) -> (EdgeStore, EdgeKey) { let store = EdgeStore::new(RuntimeHasher::default()); let subject = did("did:plc:subject"); - let kind = nsid_static("sh.tangled.feed.star"); + let kind = nsid_static("org.tangled.feed.star"); let key = EdgeKey::new(kind.clone(), SubjectRef::Did(subject.clone())); (0..edges).for_each(|index| { let author = author_for(index); let source = AtUri::new_owned(format!( - "at://did:plc:author{author}/sh.tangled.feed.star/r{index}", + "at://did:plc:author{author}/org.tangled.feed.star/r{index}", )) .expect("valid at-uri"); store.add(Edge { diff --git a/bobbin/crates/edge-index/src/lib.rs b/bobbin/crates/edge-index/src/lib.rs index 1f4570bd3..694d37084 100644 --- a/bobbin/crates/edge-index/src/lib.rs +++ b/bobbin/crates/edge-index/src/lib.rs @@ -1186,7 +1186,7 @@ impl EdgeStore { } pub fn top_starred_since(&self, since_micros: u64, limit: usize) -> Vec { - self.ranked_dids("sh.tangled.feed.star", Some(since_micros), limit) + self.ranked_dids("org.tangled.feed.star", Some(since_micros), limit) } pub fn count(&self, key: &EdgeKey) -> u64 { @@ -1827,7 +1827,7 @@ mod tests { fn star_edge_at(source: AtUri, subject: Did, sort_micros: u64) -> Edge { Edge { - kind: nsid("sh.tangled.feed.star"), + kind: nsid("org.tangled.feed.star"), subject: SubjectRef::Did(subject), source, sort_micros, @@ -1853,7 +1853,7 @@ mod tests { fn source_uri(i: usize) -> String { format!( - "at://did:plc:{}/sh.tangled.feed.star/r{i}", + "at://did:plc:{}/org.tangled.feed.star/r{i}", NAMES[i % NAMES.len()] ) } @@ -1867,7 +1867,7 @@ mod tests { shuffled_micros(i), )); }); - EdgeKey::new(nsid("sh.tangled.feed.star"), did_subj("did:plc:squid")) + EdgeKey::new(nsid("org.tangled.feed.star"), did_subj("did:plc:squid")) } fn reference(kept: impl Iterator) -> Vec { @@ -2023,20 +2023,20 @@ mod tests { let store = store(); let subject = did("did:plc:large-subject"); let key = EdgeKey::new( - nsid("sh.tangled.feed.star"), + nsid("org.tangled.feed.star"), SubjectRef::Did(subject.clone()), ); (0..255).for_each(|index| { store.add(star_edge_at( at(&format!( - "at://did:plc:author{index}/sh.tangled.feed.star/r{index}" + "at://did:plc:author{index}/org.tangled.feed.star/r{index}" )), subject.clone(), index as u64, )); }); - let older = at("at://did:plc:repeat/sh.tangled.feed.star/older"); - let newest = at("at://did:plc:repeat/sh.tangled.feed.star/newest"); + let older = at("at://did:plc:repeat/org.tangled.feed.star/older"); + let newest = at("at://did:plc:repeat/org.tangled.feed.star/newest"); store.add(star_edge_at(older.clone(), subject.clone(), 1_000)); store.add(star_edge_at(newest.clone(), subject.clone(), 2_000)); @@ -2072,13 +2072,13 @@ mod tests { let store = store(); let subject = did("did:plc:large-subject"); let key = EdgeKey::new( - nsid("sh.tangled.feed.star"), + nsid("org.tangled.feed.star"), SubjectRef::Did(subject.clone()), ); (0..255).for_each(|index| { store.add(star_edge_at( at(&format!( - "at://did:plc:author{index}/sh.tangled.feed.star/r{index}" + "at://did:plc:author{index}/org.tangled.feed.star/r{index}" )), subject.clone(), index as u64, @@ -2087,7 +2087,7 @@ mod tests { let repeated = (0..6) .map(|index| { at(&format!( - "at://did:plc:repeat/sh.tangled.feed.star/r{index}" + "at://did:plc:repeat/org.tangled.feed.star/r{index}" )) }) .collect::>(); @@ -2332,7 +2332,7 @@ mod tests { fn empty_store_descending_after_cursor_does_not_underflow() { let store = store(); let key = EdgeKey::new( - nsid("sh.tangled.feed.star"), + nsid("org.tangled.feed.star"), SubjectRef::Did(did("did:plc:empty_test")), ); let tok = PageToken::new(12345, 1); @@ -2506,7 +2506,7 @@ mod tests { .into_iter() .map(|(subj, rkey, micros)| { star_edge_at( - at(&format!("at://did:plc:x/sh.tangled.feed.star/{rkey}")), + at(&format!("at://did:plc:x/org.tangled.feed.star/{rkey}")), did(&format!("did:plc:{subj}")), micros, ) @@ -2516,7 +2516,7 @@ mod tests { .iter() .map(|s| { EdgeKey::new( - nsid("sh.tangled.feed.star"), + nsid("org.tangled.feed.star"), did_subj(&format!("did:plc:{s}")), ) }) @@ -2552,12 +2552,12 @@ mod tests { fn list_multi_dedups_source_under_two_keys() { let store = store(); // Same record (source) indexed under two subject keys, same createdAt. - let shared = at("at://did:plc:x/sh.tangled.feed.star/shared"); + let shared = at("at://did:plc:x/org.tangled.feed.star/shared"); store.add(star_edge_at(shared.clone(), did("did:plc:alpha"), 100)); store.add(star_edge_at(shared, did("did:plc:bravo"), 100)); let keys = vec![ - EdgeKey::new(nsid("sh.tangled.feed.star"), did_subj("did:plc:alpha")), - EdgeKey::new(nsid("sh.tangled.feed.star"), did_subj("did:plc:bravo")), + EdgeKey::new(nsid("org.tangled.feed.star"), did_subj("did:plc:alpha")), + EdgeKey::new(nsid("org.tangled.feed.star"), did_subj("did:plc:bravo")), ]; let page = store.list_multi(&keys, PageCursor::Start, limit(10), SortDir::Desc); assert_eq!(page.items.len(), 1); @@ -2589,18 +2589,18 @@ mod tests { #[test] fn add_then_count() { let store = store(); - let key = EdgeKey::new(nsid("sh.tangled.feed.star"), did_subj("did:plc:abalone")); + let key = EdgeKey::new(nsid("org.tangled.feed.star"), did_subj("did:plc:abalone")); store.add(star_edge( - at("at://did:plc:nel/sh.tangled.feed.star/r1"), + at("at://did:plc:nel/org.tangled.feed.star/r1"), did("did:plc:abalone"), )); store.add(star_edge( - at("at://did:plc:olaren/sh.tangled.feed.star/r2"), + at("at://did:plc:olaren/org.tangled.feed.star/r2"), did("did:plc:abalone"), )); store.add(star_edge( - at("at://did:plc:nel/sh.tangled.feed.star/r3"), + at("at://did:plc:nel/org.tangled.feed.star/r3"), did("did:plc:abalone"), )); @@ -2611,9 +2611,9 @@ mod tests { #[test] fn duplicate_add_is_idempotent() { let store = store(); - let key = EdgeKey::new(nsid("sh.tangled.feed.star"), did_subj("did:plc:abalone")); + let key = EdgeKey::new(nsid("org.tangled.feed.star"), did_subj("did:plc:abalone")); let edge = star_edge( - at("at://did:plc:nel/sh.tangled.feed.star/r1"), + at("at://did:plc:nel/org.tangled.feed.star/r1"), did("did:plc:abalone"), ); store.add(edge.clone()); @@ -2625,12 +2625,12 @@ mod tests { #[test] fn remove_source_clears_all_keys_for_that_source() { let store = store(); - let star_key = EdgeKey::new(nsid("sh.tangled.feed.star"), did_subj("did:plc:abalone")); + let star_key = EdgeKey::new(nsid("org.tangled.feed.star"), did_subj("did:plc:abalone")); let follow_key = EdgeKey::new(nsid("org.tangled.graph.follow"), did_subj("did:plc:lyna")); - let source = "at://did:plc:nel/sh.tangled.feed.star/r1"; + let source = "at://did:plc:nel/org.tangled.feed.star/r1"; store.add(Edge { - kind: nsid("sh.tangled.feed.star"), + kind: nsid("org.tangled.feed.star"), subject: did_subj("did:plc:abalone"), source: at(source), sort_micros: 0, @@ -2653,10 +2653,10 @@ mod tests { #[test] fn upsert_source_replaces_old_edges() { let store = store(); - let source = at("at://did:plc:teq/sh.tangled.feed.star/r1"); + let source = at("at://did:plc:teq/org.tangled.feed.star/r1"); let old_subject = did_subj("did:plc:abalone"); let new_subject = did_subj("did:plc:uni"); - let kind = nsid("sh.tangled.feed.star"); + let kind = nsid("org.tangled.feed.star"); store.upsert_source( &source, @@ -3106,11 +3106,11 @@ mod tests { #[test] fn list_pages_in_sort_order() { let store = store(); - let key = EdgeKey::new(nsid("sh.tangled.feed.star"), did_subj("did:plc:abalone")); + let key = EdgeKey::new(nsid("org.tangled.feed.star"), did_subj("did:plc:abalone")); (0..5).for_each(|i| { store.add(star_edge_at( at(&format!( - "at://did:plc:{}/sh.tangled.feed.star/r{i}", + "at://did:plc:{}/org.tangled.feed.star/r{i}", NAMES[i] )), did("did:plc:abalone"), @@ -3137,11 +3137,11 @@ mod tests { #[test] fn list_exact_fill_signals_exhaustion() { let store = store(); - let key = EdgeKey::new(nsid("sh.tangled.feed.star"), did_subj("did:plc:abalone")); + let key = EdgeKey::new(nsid("org.tangled.feed.star"), did_subj("did:plc:abalone")); (0..2).for_each(|i| { store.add(star_edge( at(&format!( - "at://did:plc:{}/sh.tangled.feed.star/r{i}", + "at://did:plc:{}/org.tangled.feed.star/r{i}", NAMES[i] )), did("did:plc:abalone"), @@ -3157,7 +3157,10 @@ mod tests { fn list_on_unknown_key_is_empty() { let store = store(); let page = store.list( - &EdgeKey::new(nsid("sh.tangled.feed.star"), did_subj("did:plc:periwinkle")), + &EdgeKey::new( + nsid("org.tangled.feed.star"), + did_subj("did:plc:periwinkle"), + ), PageCursor::Start, limit(10), SortDir::Asc, @@ -3169,10 +3172,10 @@ mod tests { #[test] fn distinct_authors_decreases_when_last_source_from_author_removed() { let store = store(); - let key = EdgeKey::new(nsid("sh.tangled.feed.star"), did_subj("did:plc:abalone")); - let s1 = at("at://did:plc:nel/sh.tangled.feed.star/r1"); - let s2 = at("at://did:plc:nel/sh.tangled.feed.star/r2"); - let s3 = at("at://did:plc:olaren/sh.tangled.feed.star/r3"); + let key = EdgeKey::new(nsid("org.tangled.feed.star"), did_subj("did:plc:abalone")); + let s1 = at("at://did:plc:nel/org.tangled.feed.star/r1"); + let s2 = at("at://did:plc:nel/org.tangled.feed.star/r2"); + let s3 = at("at://did:plc:olaren/org.tangled.feed.star/r3"); store.add(star_edge(s1.clone(), did("did:plc:abalone"))); store.add(star_edge(s2.clone(), did("did:plc:abalone"))); @@ -3299,13 +3302,13 @@ mod tests { let store = store(); let subject_did = did("did:plc:limpet"); let key = EdgeKey::new( - nsid("sh.tangled.feed.star"), + nsid("org.tangled.feed.star"), SubjectRef::Did(subject_did.clone()), ); (0..4).for_each(|i| { store.add(star_edge_at( at(&format!( - "at://did:plc:{}/sh.tangled.feed.star/r{i}", + "at://did:plc:{}/org.tangled.feed.star/r{i}", NAMES[i] )), subject_did.clone(), @@ -3338,13 +3341,13 @@ mod tests { let store = store(); let subject_did = did("did:plc:limpet"); let key = EdgeKey::new( - nsid("sh.tangled.feed.star"), + nsid("org.tangled.feed.star"), SubjectRef::Did(subject_did.clone()), ); (0..5).for_each(|i| { store.add(star_edge_at( at(&format!( - "at://did:plc:{}/sh.tangled.feed.star/r{i}", + "at://did:plc:{}/org.tangled.feed.star/r{i}", NAMES[i] )), subject_did.clone(), @@ -3368,13 +3371,13 @@ mod tests { let store = store(); let subject_did = did("did:plc:whelk"); let key = EdgeKey::new( - nsid("sh.tangled.feed.star"), + nsid("org.tangled.feed.star"), SubjectRef::Did(subject_did.clone()), ); (0..5).for_each(|i| { store.add(star_edge_at( at(&format!( - "at://did:plc:{}/sh.tangled.feed.star/r{i}", + "at://did:plc:{}/org.tangled.feed.star/r{i}", NAMES[i] )), subject_did.clone(), @@ -3411,11 +3414,11 @@ mod tests { let store = store(); let subject = did("did:plc:limpet"); let key = EdgeKey::new( - nsid("sh.tangled.feed.star"), + nsid("org.tangled.feed.star"), SubjectRef::Did(subject.clone()), ); - let did_source = at("at://did:plc:nel/sh.tangled.feed.star/r1"); - let handle_source = at("at://witchcraft.systems/sh.tangled.feed.star/r2"); + let did_source = at("at://did:plc:nel/org.tangled.feed.star/r1"); + let handle_source = at("at://witchcraft.systems/org.tangled.feed.star/r2"); store.add(star_edge_at(did_source.clone(), subject.clone(), 1)); store.add(star_edge_at(handle_source.clone(), subject.clone(), 2)); @@ -3444,19 +3447,19 @@ mod tests { let store = store(); let subject = did("did:plc:limpet"); let key = EdgeKey::new( - nsid("sh.tangled.feed.star"), + nsid("org.tangled.feed.star"), SubjectRef::Did(subject.clone()), ); - let star_src = at("at://did:plc:nel/sh.tangled.feed.star/aaa"); + let star_src = at("at://did:plc:nel/org.tangled.feed.star/aaa"); let issue_src = at("at://did:plc:nel/sh.tangled.repo.issue/bbb"); store.add(Edge { - kind: nsid("sh.tangled.feed.star"), + kind: nsid("org.tangled.feed.star"), subject: SubjectRef::Did(subject.clone()), source: star_src.clone(), sort_micros: 1, }); store.add(Edge { - kind: nsid("sh.tangled.feed.star"), + kind: nsid("org.tangled.feed.star"), subject: SubjectRef::Did(subject.clone()), source: issue_src.clone(), sort_micros: 2, @@ -3522,7 +3525,7 @@ mod tests { .into_iter() .for_each(|(author, rkey, subject, micros)| { store.add(star_edge_at( - at(&format!("at://{author}/sh.tangled.feed.star/{rkey}")), + at(&format!("at://{author}/org.tangled.feed.star/{rkey}")), subject, micros, )); @@ -3537,13 +3540,13 @@ mod tests { let store = store(); let subject = did("did:plc:scallop"); let key = EdgeKey::new( - nsid("sh.tangled.feed.star"), + nsid("org.tangled.feed.star"), SubjectRef::Did(subject.clone()), ); (0..5).for_each(|i| { store.add(star_edge_at( at(&format!( - "at://did:plc:{}/sh.tangled.feed.star/r{i}", + "at://did:plc:{}/org.tangled.feed.star/r{i}", NAMES[i] )), subject.clone(), @@ -3557,7 +3560,7 @@ mod tests { ); store.add(star_edge_at( - at("at://did:plc:nel/sh.tangled.feed.star/r99"), + at("at://did:plc:nel/org.tangled.feed.star/r99"), subject.clone(), 99, )); @@ -3567,13 +3570,13 @@ mod tests { "second nel source adds no author" ); - store.remove_source(&at("at://did:plc:nel/sh.tangled.feed.star/r0")); + store.remove_source(&at("at://did:plc:nel/org.tangled.feed.star/r0")); assert_eq!( store.count_distinct_authors(&key), 5, "nel still present via r99" ); - store.remove_source(&at("at://did:plc:nel/sh.tangled.feed.star/r99")); + store.remove_source(&at("at://did:plc:nel/org.tangled.feed.star/r99")); assert_eq!(store.count_distinct_authors(&key), 4, "nel fully removed"); } diff --git a/bobbin/crates/edge-index/src/settle.rs b/bobbin/crates/edge-index/src/settle.rs index a03f13479..2beab2a3e 100644 --- a/bobbin/crates/edge-index/src/settle.rs +++ b/bobbin/crates/edge-index/src/settle.rs @@ -309,7 +309,7 @@ mod tests { use super::*; fn uri(rkey: &str) -> AtUri { - AtUri::new_owned(format!("at://did:plc:alice/sh.tangled.feed.star/{rkey}")).unwrap() + AtUri::new_owned(format!("at://did:plc:alice/org.tangled.feed.star/{rkey}")).unwrap() } const CID_A: &str = "bafyreieqygohnz2zqyvtvktbjpvhutphobcmbsnt4q5lc36ri7vpcmoz4i"; diff --git a/bobbin/crates/ingest/benches/json_decode.rs b/bobbin/crates/ingest/benches/json_decode.rs index 0b7e41049..b651ac01e 100644 --- a/bobbin/crates/ingest/benches/json_decode.rs +++ b/bobbin/crates/ingest/benches/json_decode.rs @@ -75,15 +75,15 @@ fn star_text() -> &'static str { "live": false, "did": "did:plc:olaren", "rev": "3lq2zk5wqsh2k", - "collection": "sh.tangled.feed.star", + "collection": "org.tangled.feed.star", "rkey": "abcabcabcabcz", "action": "create", "record": { - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", "subject": { - "$type": "sh.tangled.feed.star#repo", - "did": "did:plc:limpet" + "$type": "org.tangled.feed.star#repo", + "identity": "did:plc:limpet" } } } diff --git a/bobbin/crates/ingest/src/analytics.rs b/bobbin/crates/ingest/src/analytics.rs index ba5b54d04..5554db3f2 100644 --- a/bobbin/crates/ingest/src/analytics.rs +++ b/bobbin/crates/ingest/src/analytics.rs @@ -7,7 +7,7 @@ use std::time::Duration; use bobbin_record_lru::RecordStore; use bobbin_types::edges::Record; use bobbin_types::ids::{RepoIdent, owner_did_from_aturi}; -use bobbin_types::sh_tangled::feed::star::StarSubject; +use bobbin_types::org_tangled::feed::star::StarSubject; use jacquard_common::DefaultStr; use jacquard_common::types::nsid::Nsid; use jacquard_common::types::string::{AtUri, Cid}; @@ -303,8 +303,8 @@ fn upsert_event( fn star_subject(subject: &StarSubject) -> (&'static str, String) { match subject { - StarSubject::Repo(repo) => ("repo", repo.did.as_ref().to_owned()), - StarSubject::String(string) => ("string", string.uri.as_ref().to_owned()), + StarSubject::Repo(repo) => ("repo", repo.identity.as_ref().to_owned()), + StarSubject::Record(record) => ("record", record.record.uri.as_ref().to_owned()), } } @@ -315,7 +315,7 @@ fn delete_event(source: &AtUri, nsid: &str, records: &dyn RecordStore) -> Option name: "delete_string", properties: props([prop("rkey", rkey_str(source))]), }), - "sh.tangled.feed.star" => { + "org.tangled.feed.star" => { let Record::Star(star) = cached_record(source, nsid, records)? else { return None; }; @@ -600,15 +600,15 @@ mod tests { let store = MapStore::default(); seed( &store, - "at://did:plc:dawn/sh.tangled.feed.star/3kzzzzzzzzzzz", + "at://did:plc:dawn/org.tangled.feed.star/3kzzzzzzzzzzz", json!({ - "$type": "sh.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subject": {"$type": "sh.tangled.feed.star#repo", "did": "did:plc:other"}, + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", + "subject": {"$type": "org.tangled.feed.star#repo", "identity": "did:plc:other"}, }), ); let Some((name, props)) = mapped_delete( - "at://did:plc:dawn/sh.tangled.feed.star/3kzzzzzzzzzzz", - "sh.tangled.feed.star", + "at://did:plc:dawn/org.tangled.feed.star/3kzzzzzzzzzzz", + "org.tangled.feed.star", &store, ) else { panic!() @@ -620,8 +620,8 @@ mod tests { let store = MapStore::default(); assert!( mapped_delete( - "at://did:plc:dawn/sh.tangled.feed.star/3kzzzzzzzzzzz", - "sh.tangled.feed.star", + "at://did:plc:dawn/org.tangled.feed.star/3kzzzzzzzzzzz", + "org.tangled.feed.star", &store, ) .is_none() @@ -665,11 +665,11 @@ mod tests { ); let store = MapStore::default(); let star = upsert( - "at://did:plc:dawn/sh.tangled.feed.star/3kzzzzzzzzzzz", - "sh.tangled.feed.star", + "at://did:plc:dawn/org.tangled.feed.star/3kzzzzzzzzzzz", + "org.tangled.feed.star", json!({ - "$type": "sh.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subject": {"$type": "sh.tangled.feed.star#repo", "did": "did:plc:other"}, + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", + "subject": {"$type": "org.tangled.feed.star#repo", "identity": "did:plc:other"}, }), ); analytics.observe_upsert(&star.source, &star.parsed, None, &rev(), None, &store); diff --git a/bobbin/crates/ingest/src/lib.rs b/bobbin/crates/ingest/src/lib.rs index c5ab5a5a6..8f6fa9747 100644 --- a/bobbin/crates/ingest/src/lib.rs +++ b/bobbin/crates/ingest/src/lib.rs @@ -2043,13 +2043,13 @@ mod tests { "live": false, "did": "did:plc:olaren", "rev": fresh_tid().as_str(), - "collection": "sh.tangled.feed.star", + "collection": "org.tangled.feed.star", "rkey": "abcabcabcabcz", "action": "create", "record": { - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subjectDid": "did:plc:abalone" + "subject": {"$type": "org.tangled.feed.star#repo", "identity": "did:plc:abalone"} } } })); @@ -2067,7 +2067,7 @@ mod tests { ) .await; let key = bobbin_types::ids::EdgeKey::new( - Nsid::new_static("sh.tangled.feed.star").unwrap(), + Nsid::new_static("org.tangled.feed.star").unwrap(), did_subj("did:plc:abalone"), ); assert_eq!(store.count(&key), 1); @@ -2079,7 +2079,7 @@ mod tests { "live": false, "did": "did:plc:olaren", "rev": fresh_tid().as_str(), - "collection": "sh.tangled.feed.star", + "collection": "org.tangled.feed.star", "rkey": "abcabcabcabcz", "action": "delete", "record": null @@ -2112,13 +2112,13 @@ mod tests { "live": false, "did": "did:plc:olaren", "rev": fresh_tid().as_str(), - "collection": "sh.tangled.feed.star", + "collection": "org.tangled.feed.star", "rkey": "abcabcabcabcz", "action": "update", "record": { - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subjectDid": subject_did.as_ref() + "subject": {"$type": "org.tangled.feed.star#repo", "identity": subject_did.as_ref()} } } })) @@ -2150,7 +2150,7 @@ mod tests { ) .await; - let kind = Nsid::new_static("sh.tangled.feed.star").unwrap(); + let kind = Nsid::new_static("org.tangled.feed.star").unwrap(); let old = bobbin_types::ids::EdgeKey::new(kind.clone(), did_subj("did:plc:abalone")); let new = bobbin_types::ids::EdgeKey::new(kind, did_subj("did:plc:uni")); assert_eq!(store.count(&old), 0); @@ -2209,13 +2209,13 @@ mod tests { "live": live, "did": "did:plc:olaren", "rev": fresh_tid().as_str(), - "collection": "sh.tangled.feed.star", + "collection": "org.tangled.feed.star", "rkey": "abcabcabcabcz", "action": "create", "record": { - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subjectDid": "did:plc:abalone" + "subject": {"$type": "org.tangled.feed.star#repo", "identity": "did:plc:abalone"} } } })) @@ -2244,19 +2244,19 @@ mod tests { "live": false, "did": "did:plc:olaren", "rev": fresh_tid().as_str(), - "collection": "sh.tangled.feed.star", + "collection": "org.tangled.feed.star", "rkey": "abcabcabcabcz", "action": "create", "cid": VALID_CID, "record": { - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subjectDid": "did:plc:abalone" + "subject": {"$type": "org.tangled.feed.star#repo", "identity": "did:plc:abalone"} } } })); let source = - AtUri::new_owned("at://did:plc:olaren/sh.tangled.feed.star/abcabcabcabcz").unwrap(); + AtUri::new_owned("at://did:plc:olaren/org.tangled.feed.star/abcabcabcabcz").unwrap(); handle_frame( frame, &store, @@ -2273,10 +2273,7 @@ mod tests { let cached = lru.get(&source).expect("hydrant cid must seed the lru"); assert_eq!(cached.cid.as_ref(), VALID_CID); let parsed: serde_json::Value = serde_json::from_slice(&cached.value).unwrap(); - assert_eq!( - parsed["subject"]["did"], "did:plc:abalone", - "legacy wire is upgraded to canon shape before caching so downstream readers see canonical fields" - ); + assert_eq!(parsed["subject"]["identity"], "did:plc:abalone"); } #[tokio::test] @@ -2284,7 +2281,7 @@ mod tests { let (store, issue_states, pull_statuses, cov, resolver) = fresh(); let lru = LruRecordStore::new(CacheCapacity::from_bytes(64 * 1024)); let source = - AtUri::new_owned("at://did:plc:olaren/sh.tangled.feed.star/abcabcabcabcz").unwrap(); + AtUri::new_owned("at://did:plc:olaren/org.tangled.feed.star/abcabcabcabcz").unwrap(); let cid: Cid = VALID_CID.parse().unwrap(); lru.put( source.clone(), @@ -2301,13 +2298,13 @@ mod tests { "live": false, "did": "did:plc:olaren", "rev": fresh_tid().as_str(), - "collection": "sh.tangled.feed.star", + "collection": "org.tangled.feed.star", "rkey": "abcabcabcabcz", "action": "update", "record": { - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subjectDid": "did:plc:abalone" + "subject": {"$type": "org.tangled.feed.star#repo", "identity": "did:plc:abalone"} } } })); @@ -2335,7 +2332,7 @@ mod tests { let (store, issue_states, pull_statuses, cov, resolver) = fresh(); let lru = LruRecordStore::new(CacheCapacity::from_bytes(64 * 1024)); let source = - AtUri::new_owned("at://did:plc:olaren/sh.tangled.feed.star/abcabcabcabcz").unwrap(); + AtUri::new_owned("at://did:plc:olaren/org.tangled.feed.star/abcabcabcabcz").unwrap(); let cid: Cid = VALID_CID.parse().unwrap(); lru.put( source.clone(), @@ -2352,7 +2349,7 @@ mod tests { "live": false, "did": "did:plc:olaren", "rev": fresh_tid().as_str(), - "collection": "sh.tangled.feed.star", + "collection": "org.tangled.feed.star", "rkey": "abcabcabcabcz", "action": "delete", "record": null @@ -2385,13 +2382,13 @@ mod tests { "live": true, "did": "did:plc:olaren", "rev": fresh_tid().as_str(), - "collection": "sh.tangled.feed.star", + "collection": "org.tangled.feed.star", "rkey": "abcabcabcabcz", "action": "create", "record": { - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subjectDid": "did:plc:abalone" + "subject": {"$type": "org.tangled.feed.star#repo", "identity": "did:plc:abalone"} } } })); @@ -2423,13 +2420,13 @@ mod tests { "live": true, "did": "did:plc:olaren", "rev": stale_tid.as_str(), - "collection": "sh.tangled.feed.star", + "collection": "org.tangled.feed.star", "rkey": "abcabcabcabcz", "action": "create", "record": { - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subjectDid": "did:plc:abalone" + "subject": {"$type": "org.tangled.feed.star#repo", "identity": "did:plc:abalone"} } } })); @@ -2606,13 +2603,13 @@ mod tests { "live": false, "did": "did:plc:olaren", "rev": fresh_tid().as_str(), - "collection": "sh.tangled.feed.star", + "collection": "org.tangled.feed.star", "rkey": rkey.as_ref(), "action": "create", "record": { - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subjectDid": "did:plc:abalone" + "subject": {"$type": "org.tangled.feed.star#repo", "identity": "did:plc:abalone"} } } }) @@ -2635,13 +2632,13 @@ mod tests { "live": false, "did": "did:plc:olaren", "rev": fresh_tid().as_str(), - "collection": "sh.tangled.feed.star", + "collection": "org.tangled.feed.star", "rkey": "prefilrkey001", "action": "create", "record": { - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subjectDid": "did:plc:abalone" + "subject": {"$type": "org.tangled.feed.star#repo", "identity": "did:plc:abalone"} } } })); @@ -2708,13 +2705,13 @@ mod tests { "live": false, "did": "did:plc:olaren", "rev": fresh_tid().as_str(), - "collection": "sh.tangled.feed.star", + "collection": "org.tangled.feed.star", "rkey": "prefilrkey001", "action": "create", "record": { - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subjectDid": "did:plc:abalone" + "subject": {"$type": "org.tangled.feed.star#repo", "identity": "did:plc:abalone"} } } })); @@ -3032,13 +3029,13 @@ mod tests { "live": false, "did": "did:plc:nel", "rev": fresh_tid().as_str(), - "collection": "sh.tangled.feed.star", + "collection": "org.tangled.feed.star", "rkey": rkey, "action": "create", "record": { - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subject": "at://did:plc:olaren/sh.tangled.repo/abcabcabcabcz" + "subject": {"$type": "org.tangled.feed.star#repo", "identity": "did:plc:abalone"} } } })) @@ -3104,13 +3101,13 @@ mod tests { "live": false, "did": "did:plc:nel", "rev": fresh_tid().as_str(), - "collection": "sh.tangled.feed.star", + "collection": "org.tangled.feed.star", "rkey": "abcabcabcabcz", "action": "create", "record": { - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subject": "at://did:plc:olaren/sh.tangled.repo/abcabcabcabcz" + "subject": {"$type": "org.tangled.feed.star#repo", "identity": "did:plc:abalone"} } } })), @@ -3673,13 +3670,14 @@ mod tests { "live": false, "did": "did:plc:olaren", "rev": fresh_tid().as_str(), - "collection": "sh.tangled.feed.star", + "collection": "sh.tangled.repo.issue", "rkey": "abcabcabcabcz", "action": "create", "record": { - "$type": "sh.tangled.feed.star", + "$type": "sh.tangled.repo.issue", "createdAt": "2026-05-01T00:00:00Z", - "subject": "at://did:plc:nel/sh.tangled.repo/abcabcabcabcz" + "title": "bug", + "repo": "at://did:plc:nel/sh.tangled.repo/abcabcabcabcz" } } })); @@ -3697,7 +3695,7 @@ mod tests { ) .await; - let nsid = Nsid::new_static("sh.tangled.feed.star").unwrap(); + let nsid = Nsid::new_static("sh.tangled.repo.issue").unwrap(); let owner_keyed = bobbin_types::ids::EdgeKey::new(nsid.clone(), did_subj("did:plc:nel")); let uri_keyed = bobbin_types::ids::EdgeKey::new( nsid, @@ -3757,13 +3755,14 @@ mod tests { "live": false, "did": "did:plc:olaren", "rev": fresh_tid().as_str(), - "collection": "sh.tangled.feed.star", + "collection": "sh.tangled.repo.issue", "rkey": "abcabcabcabcz", "action": "create", "record": { - "$type": "sh.tangled.feed.star", + "$type": "sh.tangled.repo.issue", "createdAt": "2026-05-01T00:00:00Z", - "subject": "at://did:plc:nel/sh.tangled.repo/abcabcabcabcz" + "title": "bug", + "repo": "at://did:plc:nel/sh.tangled.repo/abcabcabcabcz" } } })); @@ -3781,7 +3780,7 @@ mod tests { ) .await; - let nsid = Nsid::new_static("sh.tangled.feed.star").unwrap(); + let nsid = Nsid::new_static("sh.tangled.repo.issue").unwrap(); let uri_keyed = bobbin_types::ids::EdgeKey::new( nsid.clone(), uri_subj("at://did:plc:nel/sh.tangled.repo/abcabcabcabcz"), @@ -3809,13 +3808,13 @@ mod tests { "live": false, "did": "did:plc:olaren", "rev": fresh_tid().as_str(), - "collection": "sh.tangled.feed.star", + "collection": "org.tangled.feed.star", "rkey": "abcabcabcabcz", "action": "create", "record": { - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subjectDid": "did:plc:abalone" + "subject": {"$type": "org.tangled.feed.star#repo", "identity": "did:plc:abalone"} } } })); @@ -3833,7 +3832,7 @@ mod tests { ) .await; let key = bobbin_types::ids::EdgeKey::new( - Nsid::new_static("sh.tangled.feed.star").unwrap(), + Nsid::new_static("org.tangled.feed.star").unwrap(), did_subj("did:plc:abalone"), ); assert_eq!(store.count(&key), 1); @@ -4443,14 +4442,20 @@ mod tests { "live": false, "did": "did:plc:olaren", "rev": fresh_tid().as_str(), - "collection": "sh.tangled.feed.star", + "collection": "org.tangled.feed.star", "rkey": format!("starrkeya{idx:04}"), "action": "create", "cid": VALID_CID, "record": { - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subject": format!("at://did:plc:nel/sh.tangled.repo/{}", repo_rkey.as_ref()), + "subject": { + "$type": "org.tangled.feed.star#record", + "record": { + "uri": format!("at://did:plc:nel/sh.tangled.repo/{}", repo_rkey.as_ref()), + "cid": VALID_CID, + }, + }, } } })) @@ -4521,19 +4526,19 @@ mod tests { })) } - const STAR_URI: &str = "at://did:plc:nel/sh.tangled.feed.star/abcabcabcabcz"; + const STAR_URI: &str = "at://did:plc:nel/org.tangled.feed.star/abcabcabcabcz"; #[tokio::test] async fn an_indexed_record_is_published_as_indexed() { let watch = Arc::new(Settlements::new()); let rt = settling_runtime(&watch); let frame = star_frame( - "sh.tangled.feed.star", + "org.tangled.feed.star", "create", json!({ - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subject": "at://did:plc:olaren/sh.tangled.repo/reporkeyabcde", + "subject": {"$type": "org.tangled.feed.star#repo", "identity": "did:plc:abalone"}, }), ); run_stages(frame, &rt).await; @@ -4544,7 +4549,7 @@ mod tests { async fn a_deleted_record_is_published_as_deleted() { let watch = Arc::new(Settlements::new()); let rt = settling_runtime(&watch); - let frame = star_frame("sh.tangled.feed.star", "delete", json!(null)); + let frame = star_frame("org.tangled.feed.star", "delete", json!(null)); run_stages(frame, &rt).await; assert_eq!(published(&watch, STAR_URI), Some(RecordOutcome::Deleted)); } @@ -4570,9 +4575,9 @@ mod tests { let watch = Arc::new(Settlements::new()); let rt = settling_runtime(&watch); let frame = star_frame( - "sh.tangled.feed.star", + "org.tangled.feed.star", "create", - json!({"$type": "sh.tangled.feed.star", "subject": 17}), + json!({"$type": "org.tangled.feed.star", "subject": 17}), ); run_stages(frame, &rt).await; let got = published(&watch, STAR_URI).expect("published"); @@ -4612,12 +4617,18 @@ mod tests { ..settling_runtime(&watch) }; let frame = star_frame( - "sh.tangled.feed.star", + "org.tangled.feed.star", "create", json!({ - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subject": "at://did:plc:olaren/sh.tangled.repo/reporkeyabcde", + "subject": { + "$type": "org.tangled.feed.star#record", + "record": { + "uri": "at://did:plc:olaren/sh.tangled.repo/reporkeyabcde", + "cid": VALID_CID, + }, + }, }), ); run_stages(frame, &rt).await; diff --git a/bobbin/crates/ingest/src/metrics.rs b/bobbin/crates/ingest/src/metrics.rs index 91e2c6e9c..b3856d8ed 100644 --- a/bobbin/crates/ingest/src/metrics.rs +++ b/bobbin/crates/ingest/src/metrics.rs @@ -166,7 +166,7 @@ mod tests { .build(); let counters = Counters::new(&provider.meter("test")); counters.settled(&settlement( - "at://did:plc:nel/sh.tangled.feed.star/k1", + "at://did:plc:nel/org.tangled.feed.star/k1", RecordOutcome::Indexed, )); counters.settled(&settlement( @@ -200,16 +200,16 @@ mod tests { assert_eq!( seen, [ + [ + "collection=org.tangled.feed.star", + "outcome=indexed", + "reason=none" + ], [ "collection=other", "outcome=rejected", "reason=unknownCollection" ], - [ - "collection=sh.tangled.feed.star", - "outcome=indexed", - "reason=none" - ], ], ); } diff --git a/bobbin/crates/ingest/src/warming.rs b/bobbin/crates/ingest/src/warming.rs index 7a2a29e0e..1c52f116f 100644 --- a/bobbin/crates/ingest/src/warming.rs +++ b/bobbin/crates/ingest/src/warming.rs @@ -332,14 +332,14 @@ mod tests { fn make_upsert(source: &str) -> ParkedUpsert { let source_uri = at(source); - let star_json = br#"{"$type":"sh.tangled.feed.star","createdAt":"2026-05-01T00:00:00Z","subject":{"$type":"sh.tangled.feed.star#repo","did":"did:plc:abalone"}}"#; - let parsed = Record::from_json_bytes(&nsid_static("sh.tangled.feed.star"), star_json) + let star_json = br#"{"$type":"org.tangled.feed.star","createdAt":"2026-05-01T00:00:00Z","subject":{"$type":"org.tangled.feed.star#repo","identity":"did:plc:abalone"}}"#; + let parsed = Record::from_json_bytes(&nsid_static("org.tangled.feed.star"), star_json) .expect("star fixture parses"); ParkedUpsert { fresh: false, cursor: HydrantCursor::new(1), source: source_uri, - nsid: nsid_static("sh.tangled.feed.star"), + nsid: nsid_static("org.tangled.feed.star"), parsed, bytes: Bytes::from_static(star_json), cid: None, @@ -354,7 +354,7 @@ mod tests { let hasher = RuntimeHasher::default(); let buf = WarmingBuffer::new(hasher); let dep = RepoIdent::new(d("did:plc:nel"), r("abcabcabcabcz")); - let upsert = make_upsert("at://did:plc:starer/sh.tangled.feed.star/zzzzzzzzzzzzz"); + let upsert = make_upsert("at://did:plc:starer/org.tangled.feed.star/zzzzzzzzzzzzz"); buf.park(upsert, vec![dep.clone()]).await; let drained = buf.take_observed(&dep.owner, &dep.rkey).await; assert_eq!(drained.len(), 1); @@ -375,12 +375,12 @@ mod tests { let dep_a = RepoIdent::new(d("did:plc:nel"), r("abcabcabcabcz")); let dep_b = RepoIdent::new(d("did:plc:olaren"), r("abcabcabcabd1")); buf.park( - make_upsert("at://did:plc:starer1/sh.tangled.feed.star/aaaaaaaaaaaaa"), + make_upsert("at://did:plc:starer1/org.tangled.feed.star/aaaaaaaaaaaaa"), vec![dep_a.clone()], ) .await; buf.park( - make_upsert("at://did:plc:starer2/sh.tangled.feed.star/bbbbbbbbbbbbb"), + make_upsert("at://did:plc:starer2/org.tangled.feed.star/bbbbbbbbbbbbb"), vec![dep_b.clone()], ) .await; @@ -397,7 +397,7 @@ mod tests { let hasher = RuntimeHasher::default(); let buf = WarmingBuffer::new(hasher); buf.park( - make_upsert("at://did:plc:starer/sh.tangled.feed.star/zzzzzzzzzzzzz"), + make_upsert("at://did:plc:starer/org.tangled.feed.star/zzzzzzzzzzzzz"), vec![RepoIdent::new(d("did:plc:nel"), r("abcabcabcabcz"))], ) .await; @@ -416,7 +416,7 @@ mod tests { let hasher = RuntimeHasher::default(); let buf = WarmingBuffer::new(hasher); let dep = RepoIdent::new(d("did:plc:nel"), r("abcabcabcabcz")); - let source = "at://did:plc:starer/sh.tangled.feed.star/zzzzzzzzzzzzz"; + let source = "at://did:plc:starer/org.tangled.feed.star/zzzzzzzzzzzzz"; buf.park(make_upsert(source), vec![dep.clone()]).await; let evicted = buf.evict_source(&at(source)).await; assert!(evicted); @@ -436,7 +436,7 @@ mod tests { let buf = WarmingBuffer::new(hasher); let dep_a = RepoIdent::new(d("did:plc:nel"), r("abcabcabcabcz")); let dep_b = RepoIdent::new(d("did:plc:olaren"), r("abcabcabcabd1")); - let source = "at://did:plc:starer/sh.tangled.feed.star/zzzzzzzzzzzzz"; + let source = "at://did:plc:starer/org.tangled.feed.star/zzzzzzzzzzzzz"; buf.park(make_upsert(source), vec![dep_a.clone(), dep_b.clone()]) .await; assert!(buf.evict_source(&at(source)).await); @@ -453,7 +453,7 @@ mod tests { let hasher = RuntimeHasher::default(); let buf = WarmingBuffer::new(hasher); let dep = RepoIdent::new(d("did:plc:nel"), r("abcabcabcabcz")); - let source = "at://did:plc:starer/sh.tangled.feed.star/zzzzzzzzzzzzz"; + let source = "at://did:plc:starer/org.tangled.feed.star/zzzzzzzzzzzzz"; buf.park(make_upsert(source), vec![dep.clone()]).await; buf.park(make_upsert(source), vec![dep.clone()]).await; let s = buf.snapshot(); @@ -467,7 +467,7 @@ mod tests { let hasher = RuntimeHasher::default(); let buf = WarmingBuffer::new(hasher); let dep = RepoIdent::new(d("did:plc:nel"), r("abcabcabcabcz")); - let source = "at://did:plc:starer/sh.tangled.feed.star/zzzzzzzzzzzzz"; + let source = "at://did:plc:starer/org.tangled.feed.star/zzzzzzzzzzzzz"; buf.park(make_upsert(source), vec![dep.clone()]).await; buf.park(make_upsert(source), vec![dep.clone()]).await; let drained = buf.take_observed(&dep.owner, &dep.rkey).await; @@ -487,7 +487,7 @@ mod tests { let buf = WarmingBuffer::new(hasher); let dep = RepoIdent::new(d("did:plc:nel"), r("abcabcabcabcz")); buf.park( - make_upsert("at://did:plc:starer/sh.tangled.feed.star/zzzzzzzzzzzzz"), + make_upsert("at://did:plc:starer/org.tangled.feed.star/zzzzzzzzzzzzz"), vec![dep], ) .await; @@ -504,7 +504,7 @@ mod tests { let buf = WarmingBuffer::new(hasher); let dep = RepoIdent::new(d("did:plc:nel"), r("abcabcabcabcz")); let _ = buf.drain_for_promote().await; - let upsert = make_upsert("at://did:plc:starer/sh.tangled.feed.star/zzzzzzzzzzzzz"); + let upsert = make_upsert("at://did:plc:starer/org.tangled.feed.star/zzzzzzzzzzzzz"); let res = buf.try_park(upsert, vec![dep]).await; assert!(res.is_err(), "post-seal try_park must reject"); let s = buf.snapshot(); @@ -519,7 +519,7 @@ mod tests { let buf = WarmingBuffer::new(hasher); let dep = RepoIdent::new(d("did:plc:nel"), r("abcabcabcabcz")); buf.park( - make_upsert("at://did:plc:starer/sh.tangled.feed.star/zzzzzzzzzzzzz"), + make_upsert("at://did:plc:starer/org.tangled.feed.star/zzzzzzzzzzzzz"), vec![dep.clone()], ) .await; diff --git a/bobbin/crates/resolver/src/legacy_upgrade.rs b/bobbin/crates/resolver/src/legacy_upgrade.rs index dc297c0fc..99a6990b9 100644 --- a/bobbin/crates/resolver/src/legacy_upgrade.rs +++ b/bobbin/crates/resolver/src/legacy_upgrade.rs @@ -4,10 +4,9 @@ use bobbin_types::edges::{ExtractError, Record}; use bobbin_types::legacy::{ LEGACY_COMMENT_SENTINEL_CID, LegacyCollaborator, LegacyIssue, LegacyIssueComment, LegacyPublicKey, LegacyPull, LegacyPullComment, LegacyRecord, LegacyRepo, LegacySource, - LegacyStar, LegacyTarget, + LegacyTarget, }; use bobbin_types::sh_tangled::feed::comment::Comment as FeedComment; -use bobbin_types::sh_tangled::feed::star::{Repo as StarRepo, Star, StarString, StarSubject}; use bobbin_types::sh_tangled::markup::markdown::Markdown; use bobbin_types::sh_tangled::public_key::PublicKey; use bobbin_types::sh_tangled::repo::Repo; @@ -21,11 +20,8 @@ use jacquard_common::types::string::{AtUri, AtprotoStr, Cid}; use jacquard_common::types::value::{Array, Data}; use jacquard_common::{BosStr, DefaultStr}; -use crate::normalize::{is_repo_at_uri, resolve_repo_uri}; -use crate::{RepoIdResolver, Resolution}; -use jacquard_common::IntoStatic; -use jacquard_common::types::ident::AtIdentifier; -use jacquard_common::types::recordkey::Rkey; +use crate::RepoIdResolver; +use crate::normalize::resolve_repo_uri; #[derive(Debug)] pub enum DecodedRecord { @@ -205,12 +201,11 @@ fn serialize_canon_variant(record: &Record) -> Result, serde Record::Issue(r) => serde_json::to_vec(r), Record::Pull(r) => serde_json::to_vec(r), Record::Collaborator(r) => serde_json::to_vec(r), - Record::Star(r) => serde_json::to_vec(r), Record::PublicKey(r) => serde_json::to_vec(r), Record::Repo(r) => serde_json::to_vec(r), - _ => unreachable!( - "upgrade only produces FeedComment/Issue/Pull/Collaborator/Star/PublicKey/Repo" - ), + _ => { + unreachable!("upgrade only produces FeedComment/Issue/Pull/Collaborator/PublicKey/Repo") + } } } @@ -223,7 +218,6 @@ pub async fn upgrade(legacy: LegacyRecord, resolver: &RepoIdResolver) -> Option< LegacyRecord::Collaborator(l) => upgrade_collaborator(l, resolver) .await .map(Record::Collaborator), - LegacyRecord::Star(l) => upgrade_star(l, resolver).await.map(Record::Star), LegacyRecord::PublicKey(l) => Some(Record::PublicKey(upgrade_public_key(l))), LegacyRecord::Repo(l) => Some(Record::Repo(upgrade_repo(l))), } @@ -422,55 +416,6 @@ async fn upgrade_collaborator( }) } -async fn upgrade_star( - l: LegacyStar, - resolver: &RepoIdResolver, -) -> Option> { - let subject = if let Some(did) = l.subject_did { - StarSubject::Repo(alloc::boxed::Box::new(StarRepo { - did, - extra_data: None, - })) - } else { - let uri = l.subject?; - let resolved = if is_repo_at_uri(&uri) { - cached_repo_did(resolver, &uri).await - } else { - None - }; - match resolved { - Some(did) => StarSubject::Repo(alloc::boxed::Box::new(StarRepo { - did, - extra_data: None, - })), - None => StarSubject::String(alloc::boxed::Box::new(StarString { - uri, - extra_data: None, - })), - } - }; - Some(Star { - created_at: l.created_at, - subject, - extra_data: l.extra_data, - }) -} - -async fn cached_repo_did( - resolver: &RepoIdResolver, - uri: &jacquard_common::types::string::AtUri, -) -> Option> { - let owner = match uri.authority() { - AtIdentifier::Did(d) => d.clone().into_static(), - AtIdentifier::Handle(_) => return None, - }; - let rkey: Rkey = uri.rkey()?.clone().into_static(); - match resolver.cached_resolution(&owner, &rkey).await? { - Resolution::Mapped(did) => Some(did), - Resolution::NoRepoDid | Resolution::Unresolvable => None, - } -} - extern crate alloc; #[cfg(test)] @@ -921,69 +866,6 @@ mod tests { } } - #[tokio::test] - async fn upgrade_star_prefers_subject_did_over_subject_uri() { - let resolver = RepoIdResolver::detached(RuntimeHasher::default()); - let json = br#"{"$type":"sh.tangled.feed.star","createdAt":"2026-05-01T00:00:00Z","subject":"at://did:plc:nel/sh.tangled.string/k1","subjectDid":"did:plc:scallop"}"#; - let legacy = - LegacyRecord::from_json_bytes(&nsid("sh.tangled.feed.star"), json).expect("decode"); - let canon = upgrade(legacy, &resolver).await.expect("upgrade"); - match canon { - Record::Star(s) => match s.subject { - StarSubject::Repo(r) => assert_eq!(r.did, did("did:plc:scallop")), - StarSubject::String(_) => panic!("subjectDid must win"), - }, - other => panic!("expected canon star, got {other:?}"), - } - } - - #[tokio::test] - async fn upgrade_star_falls_back_to_string_when_repo_uri_not_in_cache() { - let resolver = RepoIdResolver::detached(RuntimeHasher::default()); - let json = br#"{"$type":"sh.tangled.feed.star","createdAt":"2026-05-01T00:00:00Z","subject":"at://did:plc:nel/sh.tangled.repo/abcabcabcabcz"}"#; - let legacy = - LegacyRecord::from_json_bytes(&nsid("sh.tangled.feed.star"), json).expect("decode"); - let canon = upgrade(legacy, &resolver).await.expect("upgrade"); - match canon { - Record::Star(s) => match s.subject { - StarSubject::String(s) => assert_eq!( - s.uri.as_ref(), - "at://did:plc:nel/sh.tangled.repo/abcabcabcabcz", - "cache-miss on repo uri preserves the uri under the #string variant for later normalization", - ), - StarSubject::Repo(_) => panic!("cold cache must not upgrade to Repo variant"), - }, - other => panic!("expected canon star, got {other:?}"), - } - } - - #[tokio::test] - async fn upgrade_star_uses_cached_repo_did_when_observed() { - let resolver = RepoIdResolver::detached(RuntimeHasher::default()); - let owner = did("did:plc:nel"); - let key = rkey("abcabcabcabcz"); - resolver - .observe( - owner.clone(), - key.clone(), - Some(did("did:plc:scallop")), - None, - &Datetime::raw_str("2026-05-01T00:00:00Z"), - ) - .await; - let json = br#"{"$type":"sh.tangled.feed.star","createdAt":"2026-05-01T00:00:00Z","subject":"at://did:plc:nel/sh.tangled.repo/abcabcabcabcz"}"#; - let legacy = - LegacyRecord::from_json_bytes(&nsid("sh.tangled.feed.star"), json).expect("decode"); - let canon = upgrade(legacy, &resolver).await.expect("upgrade"); - match canon { - Record::Star(s) => match s.subject { - StarSubject::Repo(r) => assert_eq!(r.did, did("did:plc:scallop")), - StarSubject::String(_) => panic!("observed cache must upgrade to Repo variant"), - }, - other => panic!("expected canon star, got {other:?}"), - } - } - #[tokio::test] async fn upgrade_collaborator_requires_repo_did() { let resolver = RepoIdResolver::detached(RuntimeHasher::default()); diff --git a/bobbin/crates/resolver/src/normalize.rs b/bobbin/crates/resolver/src/normalize.rs index f33061044..e5941a23a 100644 --- a/bobbin/crates/resolver/src/normalize.rs +++ b/bobbin/crates/resolver/src/normalize.rs @@ -105,11 +105,11 @@ macro_rules! identity_normalize { } use bobbin_types::org_tangled::actor::profile::Profile; +use bobbin_types::org_tangled::feed::star::Star; use bobbin_types::org_tangled::graph::follow::Follow; use bobbin_types::org_tangled::graph::vouch::Vouch; use bobbin_types::sh_tangled::feed::comment::Comment as FeedComment; use bobbin_types::sh_tangled::feed::reaction::Reaction; -use bobbin_types::sh_tangled::feed::star::Star; use bobbin_types::sh_tangled::knot::Knot; use bobbin_types::sh_tangled::label::definition::Definition as LabelDefinition; use bobbin_types::sh_tangled::label::op::Op as LabelOp; diff --git a/bobbin/crates/types/src/edges.rs b/bobbin/crates/types/src/edges.rs index 355da1af5..62e4c522f 100644 --- a/bobbin/crates/types/src/edges.rs +++ b/bobbin/crates/types/src/edges.rs @@ -9,12 +9,12 @@ use jacquard_common::{BosStr, DefaultStr}; use crate::ids::{SubjectRef, nsid_static}; use crate::org_tangled::actor::profile::Profile; +use crate::org_tangled::feed::star::Star; use crate::org_tangled::feed::subscription::Subscription; use crate::org_tangled::graph::follow::Follow; use crate::org_tangled::graph::vouch::Vouch; use crate::sh_tangled::feed::comment::Comment as FeedCommentRecord; use crate::sh_tangled::feed::reaction::Reaction; -use crate::sh_tangled::feed::star::Star; use crate::sh_tangled::knot::Knot; use crate::sh_tangled::label::definition::Definition as LabelDefinitionRecord; use crate::sh_tangled::label::op::Op as LabelOpRecord; @@ -101,7 +101,7 @@ impl Record { "org.tangled.actor.profile" => parse!(Profile), "sh.tangled.feed.comment" => parse!(FeedComment), "sh.tangled.feed.reaction" => parse!(Reaction), - "sh.tangled.feed.star" => parse!(Star), + "org.tangled.feed.star" => parse!(Star), "org.tangled.feed.subscription" => parse!(Subscription), "org.tangled.graph.follow" => parse!(Follow), "org.tangled.graph.vouch" => parse!(Vouch), @@ -130,7 +130,7 @@ impl Record { Self::Profile(_) => "org.tangled.actor.profile", Self::FeedComment(_) => "sh.tangled.feed.comment", Self::Reaction(_) => "sh.tangled.feed.reaction", - Self::Star(_) => "sh.tangled.feed.star", + Self::Star(_) => "org.tangled.feed.star", Self::Subscription(_) => "org.tangled.feed.subscription", Self::Follow(_) => "org.tangled.graph.follow", Self::Vouch(_) => "org.tangled.graph.vouch", @@ -284,7 +284,7 @@ fn one_edge(kind: &'static str, subject: SubjectRef, source: &AtUri) } const GLOBAL_KINDS: &[&str] = &[ - "sh.tangled.feed.star", + "org.tangled.feed.star", "org.tangled.graph.follow", "sh.tangled.repo", ]; @@ -307,7 +307,7 @@ fn global_edges(primary: &[Edge]) -> Vec { const MIRROR_KINDS: &[(&str, &str)] = &[ ("sh.tangled.feed.comment", "sh.tangled.feed.comment.by"), - ("sh.tangled.feed.star", "sh.tangled.feed.star.by"), + ("org.tangled.feed.star", "org.tangled.feed.star.by"), ("sh.tangled.feed.reaction", "sh.tangled.feed.reaction.by"), ("org.tangled.graph.follow", "org.tangled.graph.follow.by"), ("org.tangled.graph.vouch", "org.tangled.graph.vouch.by"), @@ -386,17 +386,17 @@ fn star_edges( source: &AtUri, record: &Star, ) -> Result, ExtractError> { - use crate::sh_tangled::feed::star::StarSubject; + use crate::org_tangled::feed::star::StarSubject; let subject = match &record.subject { - StarSubject::Repo(r) => SubjectRef::Did(r.did.clone()), - StarSubject::String(s) => { - let Some(uri_subject) = uri_subject_for_record(&s.uri) else { + StarSubject::Repo(r) => SubjectRef::Did(r.identity.clone()), + StarSubject::Record(r) => { + let Some(uri_subject) = uri_subject_for_record(&r.record.uri) else { return Ok(Vec::new()); }; uri_subject } }; - Ok(one_edge("sh.tangled.feed.star", subject, source)) + Ok(one_edge("org.tangled.feed.star", subject, source)) } fn subscription_edges( @@ -705,12 +705,12 @@ mod tests { fn global_edge_emitted_for_allowlisted_kinds() { let cases = [ ( - "sh.tangled.feed.star", - "at://did:plc:olaren/sh.tangled.feed.star/abcabcabcabcz", + "org.tangled.feed.star", + "at://did:plc:olaren/org.tangled.feed.star/abcabcabcabcz", json!({ - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subject": { "$type": "sh.tangled.feed.star#repo", "did": "did:plc:abalone" } + "subject": { "$type": "org.tangled.feed.star#repo", "identity": "did:plc:abalone" } }), ), ( @@ -762,39 +762,39 @@ mod tests { #[test] fn star_repo_variant_keys_on_did() { let edges = extract( - "sh.tangled.feed.star", - "at://did:plc:olaren/sh.tangled.feed.star/abcabcabcabcz", + "org.tangled.feed.star", + "at://did:plc:olaren/org.tangled.feed.star/abcabcabcabcz", json!({ - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", "subject": { - "$type": "sh.tangled.feed.star#repo", - "did": "did:plc:abalone" + "$type": "org.tangled.feed.star#repo", + "identity": "did:plc:abalone" } }), ); assert_eq!( edges, vec![Edge { - kind: nsid("sh.tangled.feed.star"), + kind: nsid("org.tangled.feed.star"), subject: did_subj("did:plc:abalone"), - source: at("at://did:plc:olaren/sh.tangled.feed.star/abcabcabcabcz"), + source: at("at://did:plc:olaren/org.tangled.feed.star/abcabcabcabcz"), sort_micros: 0, }] ); } #[test] - fn star_string_variant_keeps_full_path() { + fn star_record_variant_keeps_full_path() { let edges = extract( - "sh.tangled.feed.star", - "at://did:plc:olaren/sh.tangled.feed.star/abcabcabcabcz", + "org.tangled.feed.star", + "at://did:plc:olaren/org.tangled.feed.star/abcabcabcabcz", json!({ - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", "subject": { - "$type": "sh.tangled.feed.star#string", - "uri": "at://did:plc:teq/sh.tangled.string/k1" + "$type": "org.tangled.feed.star#record", + "record": { "uri": "at://did:plc:teq/sh.tangled.string/k1", "cid": "bafkqaaa" } } }), ); @@ -806,16 +806,16 @@ mod tests { } #[test] - fn star_string_variant_handle_authority_emits_no_edge() { + fn star_record_variant_handle_authority_emits_no_edge() { let edges = extract( - "sh.tangled.feed.star", - "at://did:plc:olaren/sh.tangled.feed.star/abcabcabcabcz", + "org.tangled.feed.star", + "at://did:plc:olaren/org.tangled.feed.star/abcabcabcabcz", json!({ - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", "subject": { - "$type": "sh.tangled.feed.star#string", - "uri": "at://oyster.cafe/sh.tangled.repo/r1" + "$type": "org.tangled.feed.star#record", + "record": { "uri": "at://oyster.cafe/sh.tangled.repo/r1", "cid": "bafkqaaa" } } }), ); diff --git a/bobbin/crates/types/src/ids.rs b/bobbin/crates/types/src/ids.rs index b844c9982..c47c18b60 100644 --- a/bobbin/crates/types/src/ids.rs +++ b/bobbin/crates/types/src/ids.rs @@ -107,7 +107,7 @@ mod tests { #[test] fn owner_did_from_full_uri() { assert_eq!( - owner_did_from_aturi(&at("at://did:plc:olaren/sh.tangled.feed.star/3lk1")), + owner_did_from_aturi(&at("at://did:plc:olaren/org.tangled.feed.star/3lk1")), Some(did("did:plc:olaren")), ); } diff --git a/bobbin/crates/types/src/legacy.rs b/bobbin/crates/types/src/legacy.rs index d9edbd9be..8a75c456a 100644 --- a/bobbin/crates/types/src/legacy.rs +++ b/bobbin/crates/types/src/legacy.rs @@ -174,23 +174,6 @@ pub struct LegacyCollaborator { pub extra_data: Option>>, } -#[derive(Debug, Deserialize)] -#[serde( - rename_all = "camelCase", - rename = "sh.tangled.feed.star", - tag = "$type", - bound(deserialize = "S: Deserialize<'de> + BosStr") -)] -pub struct LegacyStar { - pub created_at: Datetime, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub subject: Option>, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub subject_did: Option>, - #[serde(flatten, default, skip_serializing_if = "Option::is_none")] - pub extra_data: Option>>, -} - #[derive(Debug, Deserialize)] #[serde( rename_all = "camelCase", @@ -233,7 +216,6 @@ pub enum LegacyRecord { Pull(Box>), PullComment(LegacyPullComment), Collaborator(LegacyCollaborator), - Star(LegacyStar), PublicKey(LegacyPublicKey), Repo(LegacyRepo), } @@ -253,7 +235,6 @@ impl LegacyRecord { "sh.tangled.repo.collaborator" => { Ok(Self::Collaborator(serde_json::from_slice(bytes)?)) } - "sh.tangled.feed.star" => Ok(Self::Star(serde_json::from_slice(bytes)?)), "sh.tangled.publicKey" => Ok(Self::PublicKey(serde_json::from_slice(bytes)?)), "sh.tangled.repo" => Ok(Self::Repo(serde_json::from_slice(bytes)?)), other => Err(ExtractError::UnknownCollection(other.into())), diff --git a/bobbin/crates/types/src/search.rs b/bobbin/crates/types/src/search.rs index 0b6f9622f..4f7ab9f7b 100644 --- a/bobbin/crates/types/src/search.rs +++ b/bobbin/crates/types/src/search.rs @@ -359,13 +359,13 @@ mod tests { #[test] fn non_text_records_have_no_searchable_view() { let parsed = Record::from_json_value( - &nsid("sh.tangled.feed.star"), + &nsid("org.tangled.feed.star"), json!({ - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", "subject": { - "$type": "sh.tangled.feed.star#repo", - "did": "did:plc:squid" + "$type": "org.tangled.feed.star#repo", + "identity": "did:plc:squid" } }), ) @@ -411,15 +411,15 @@ mod tests { #[test] fn from_json_bytes_rejects_unknown_nsid() { let body = json!({ - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", "subject": { - "$type": "sh.tangled.feed.star#repo", - "did": "did:plc:squid" + "$type": "org.tangled.feed.star#repo", + "identity": "did:plc:squid" } }); let bytes = serde_json::to_vec(&body).unwrap(); - let err = SearchableRecord::from_json_bytes(&nsid("sh.tangled.feed.star"), &bytes) + let err = SearchableRecord::from_json_bytes(&nsid("org.tangled.feed.star"), &bytes) .expect_err("non-searchable nsid must be rejected at search hydration"); assert!(matches!(err, ExtractError::UnknownCollection(_))); } diff --git a/bobbin/crates/xrpc/src/actor.rs b/bobbin/crates/xrpc/src/actor.rs index e67e98017..327d9037c 100644 --- a/bobbin/crates/xrpc/src/actor.rs +++ b/bobbin/crates/xrpc/src/actor.rs @@ -157,9 +157,9 @@ mod tests { .into_iter() .for_each(|(author, rkey, subject, sort_micros)| { edges.add(Edge { - kind: nsid_static("sh.tangled.feed.star"), + kind: nsid_static("org.tangled.feed.star"), subject: SubjectRef::Did(subject), - source: AtUri::new_owned(format!("at://{author}/sh.tangled.feed.star/{rkey}")) + source: AtUri::new_owned(format!("at://{author}/org.tangled.feed.star/{rkey}")) .unwrap(), sort_micros, }); diff --git a/bobbin/crates/xrpc/src/enrich.rs b/bobbin/crates/xrpc/src/enrich.rs index f894383d1..35cae82dc 100644 --- a/bobbin/crates/xrpc/src/enrich.rs +++ b/bobbin/crates/xrpc/src/enrich.rs @@ -696,13 +696,13 @@ mod tests { #[test] fn parses_link_sources_and_payload_types() { - let source = LinkSource::parse("sh.tangled.feed.star:subject").unwrap(); - assert_eq!(source.collection.as_ref(), "sh.tangled.feed.star"); + let source = LinkSource::parse("org.tangled.feed.star:subject").unwrap(); + assert_eq!(source.collection.as_ref(), "org.tangled.feed.star"); assert_eq!(source.path, SourcePath::Subject); let source = LinkSource::parse("org.tangled.graph.follow:.repo").unwrap(); assert_eq!(source.path, SourcePath::Repo); - assert!(LinkSource::parse("sh.tangled.feed.star").is_err()); - assert!(LinkSource::parse("sh.tangled.feed.star:.rkey").is_err()); + assert!(LinkSource::parse("org.tangled.feed.star").is_err()); + assert!(LinkSource::parse("org.tangled.feed.star:.rkey").is_err()); assert!(LinkSource::parse("not an nsid:subject").is_err()); let source = LinkSource::parse("sh.tangled.repo:.").unwrap(); assert_eq!(source.path, SourcePath::Itself); diff --git a/bobbin/crates/xrpc/src/feed.rs b/bobbin/crates/xrpc/src/feed.rs index 1c2335a02..56d5e86ec 100644 --- a/bobbin/crates/xrpc/src/feed.rs +++ b/bobbin/crates/xrpc/src/feed.rs @@ -9,6 +9,7 @@ use bobbin_edge_index::{ EdgeItem, EdgePage, EdgeStore, PageCursor, PageLimit, PageOffset, PageToken, SortDir, }; use bobbin_types::ids::{EdgeKey, SubjectRef, nsid_static, owner_did_from_aturi}; +use bobbin_types::org_tangled::feed::star::{Star, StarRecord, StarSubject}; use bobbin_types::org_tangled::graph::follow::{Follow, FollowRecord}; use bobbin_types::sh_tangled::actor::{ProfileViewBasic, ProfileViewDetailed, ViewerState}; use bobbin_types::sh_tangled::embed::commit::View as CommitEmbedView; @@ -17,7 +18,6 @@ use bobbin_types::sh_tangled::feed::comment::{Comment, CommentRecord}; use bobbin_types::sh_tangled::feed::get_timeline::{ FollowEvent, RepoEvent, StarEvent, TimelineItem, TimelineItemEvent, }; -use bobbin_types::sh_tangled::feed::star::{Star, StarRecord, StarSubject}; use bobbin_types::sh_tangled::repo::{Repo, RepoRecord}; use jacquard_axum::service_auth::ExtractOptionalServiceAuth; use jacquard_common::types::string::{AtUri, Datetime, Did, Handle, UriValue}; @@ -32,9 +32,9 @@ use crate::{ }; const REPO_NSID: &str = "sh.tangled.repo"; -const STAR_NSID: &str = "sh.tangled.feed.star"; +const STAR_NSID: &str = "org.tangled.feed.star"; const FOLLOW_NSID: &str = "org.tangled.graph.follow"; -const STAR_BY_NSID: &str = "sh.tangled.feed.star.by"; +const STAR_BY_NSID: &str = "org.tangled.feed.star.by"; const FOLLOW_BY_NSID: &str = "org.tangled.graph.follow.by"; const HYDRATE_CONCURRENCY: usize = 8; @@ -284,8 +284,8 @@ async fn hydrate_star_event( .ok_or_else(|| XrpcError::InvalidParams("star uri authority must be a did".into()))?; let actor = build_profile_basic(state, viewer, &starrer).await; let repo_did = match &star.subject { - StarSubject::Repo(r) => r.did.clone(), - StarSubject::String(_) => { + StarSubject::Repo(r) => r.identity.clone(), + StarSubject::Record(_) => { return Err(XrpcError::InvalidRecord( "timeline star subject is not a repo".into(), )); diff --git a/bobbin/crates/xrpc/src/lib.rs b/bobbin/crates/xrpc/src/lib.rs index 74069fe39..1a20fb54b 100644 --- a/bobbin/crates/xrpc/src/lib.rs +++ b/bobbin/crates/xrpc/src/lib.rs @@ -43,6 +43,7 @@ use bobbin_types::edges::REPO_SOURCE_EDGE_KIND; use bobbin_types::ids::{EdgeKey, SubjectRef, nsid_static, owner_did_from_aturi}; use bobbin_types::knot_acl::{KnotOwnedSource, decode_knot_owned_source}; use bobbin_types::org_tangled::actor::profile::{Profile, ProfileGetRecordOutput, ProfileRecord}; +use bobbin_types::org_tangled::feed::star::{Star, StarRecord}; use bobbin_types::org_tangled::feed::subscription::SubscriptionRecord; use bobbin_types::org_tangled::graph::follow::{Follow, FollowRecord}; use bobbin_types::org_tangled::graph::vouch::{Vouch, VouchRecord}; @@ -52,7 +53,6 @@ use bobbin_types::sh_tangled::feed::comment::{ Comment as FeedComment, CommentRecord as FeedCommentRecord, }; use bobbin_types::sh_tangled::feed::reaction::{Reaction, ReactionRecord}; -use bobbin_types::sh_tangled::feed::star::{Star, StarRecord}; use bobbin_types::sh_tangled::knot::{Knot, KnotRecord}; use bobbin_types::sh_tangled::label::definition::{ Definition as LabelDefinition, DefinitionRecord as LabelDefinitionRecord, @@ -1377,7 +1377,7 @@ macro_rules! edge_kinds { } edge_kinds! { - "sh.tangled.feed.star" => StarRecord, SubjectShape::BareDidOrOneOfCollections(&["sh.tangled.string"]), mirror StarBy; + "org.tangled.feed.star" => StarRecord, SubjectShape::BareDidOrOneOfCollections(&["sh.tangled.string"]), mirror StarBy; "sh.tangled.feed.comment" => FeedCommentRecord, SubjectShape::OneOfCollections(&["sh.tangled.repo.issue", "sh.tangled.repo.pull", "sh.tangled.string"]), mirror FeedCommentBy; "sh.tangled.feed.reaction" => ReactionRecord, SubjectShape::AnyAtUri, mirror ReactionBy; "org.tangled.graph.follow" => FollowRecord, SubjectShape::BareDid, mirror FollowBy; diff --git a/bobbin/crates/xrpc/src/view.rs b/bobbin/crates/xrpc/src/view.rs index 19e2e5f3f..c7ed04e9d 100644 --- a/bobbin/crates/xrpc/src/view.rs +++ b/bobbin/crates/xrpc/src/view.rs @@ -2,10 +2,9 @@ use bobbin_edge_index::{EdgeStore, IssueStateKind, PullStatusKind}; use bobbin_types::{ edges::REPO_SOURCE_EDGE_KIND, ids::{EdgeKey, SubjectRef, nsid_static, owner_did_from_aturi}, - org_tangled::graph::follow::FollowRecord, + org_tangled::{feed::star::StarRecord, graph::follow::FollowRecord}, sh_tangled::{ actor, - feed::star::StarRecord, repo::{self, Repo, RepoRecord, issue::IssueRecord, pull::PullRecord}, }, }; diff --git a/bobbin/crates/xrpc/tests/aggregation.rs b/bobbin/crates/xrpc/tests/aggregation.rs index 2f98fec7e..3319510a3 100644 --- a/bobbin/crates/xrpc/tests/aggregation.rs +++ b/bobbin/crates/xrpc/tests/aggregation.rs @@ -238,11 +238,11 @@ fn pull_body(repo_did: &Did, title: &str) -> Value { fn star_body(subject_did: &Did) -> Value { json!({ - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", "subject": { - "$type": "sh.tangled.feed.star#repo", - "did": subject_did.as_ref() + "$type": "org.tangled.feed.star#repo", + "identity": subject_did.as_ref() } }) } @@ -355,19 +355,19 @@ async fn count_distinct_authors_dedupes_per_author() { let h = Harness::new().await; let subject = at("at://did:plc:abalone"); h.add_edge( - &nsid("sh.tangled.feed.star"), + &nsid("org.tangled.feed.star"), &subject, - &at("at://did:plc:nel/sh.tangled.feed.star/s1"), + &at("at://did:plc:nel/org.tangled.feed.star/s1"), ); h.add_edge( - &nsid("sh.tangled.feed.star"), + &nsid("org.tangled.feed.star"), &subject, - &at("at://did:plc:nel/sh.tangled.feed.star/s2"), + &at("at://did:plc:nel/org.tangled.feed.star/s2"), ); h.add_edge( - &nsid("sh.tangled.feed.star"), + &nsid("org.tangled.feed.star"), &subject, - &at("at://did:plc:olaren/sh.tangled.feed.star/s3"), + &at("at://did:plc:olaren/org.tangled.feed.star/s3"), ); let app = router(h.state.clone()); @@ -398,17 +398,17 @@ async fn list_stars_pages_one_newest_record_per_author() { let author = did(author); let record_key = rkey(record_key); h.add_edge( - &nsid("sh.tangled.feed.star"), + &nsid("org.tangled.feed.star"), &subject, &at(&format!( - "at://{}/sh.tangled.feed.star/{}", + "at://{}/org.tangled.feed.star/{}", author.as_ref(), record_key.as_ref(), )), ); h.mount( &author, - &nsid("sh.tangled.feed.star"), + &nsid("org.tangled.feed.star"), &record_key, star_body(&subject_did), ) @@ -579,13 +579,13 @@ async fn list_items_stable_across_coverage_promotion() { let subject = at("at://did:plc:abalone"); let nel = did("did:plc:nel"); h.add_edge( - &nsid("sh.tangled.feed.star"), + &nsid("org.tangled.feed.star"), &subject, - &at(&format!("at://{}/sh.tangled.feed.star/s1", nel.as_ref())), + &at(&format!("at://{}/org.tangled.feed.star/s1", nel.as_ref())), ); h.mount( &nel, - &nsid("sh.tangled.feed.star"), + &nsid("org.tangled.feed.star"), &rkey("s1"), star_body(&did("did:plc:abalone")), ) @@ -1244,9 +1244,9 @@ async fn get_star_returns_uri_when_present_and_404_otherwise() { let repo_did = did("did:plc:limpet"); let subject = at(&format!("at://{}", repo_did.as_ref())); h.add_edge( - &nsid("sh.tangled.feed.star"), + &nsid("org.tangled.feed.star"), &subject, - &at("at://did:plc:nel/sh.tangled.feed.star/s1"), + &at("at://did:plc:nel/org.tangled.feed.star/s1"), ); let app = router(h.state.clone()); @@ -1262,7 +1262,7 @@ async fn get_star_returns_uri_when_present_and_404_otherwise() { ) .await; assert_eq!(status, StatusCode::OK); - assert_eq!(body["uri"], "at://did:plc:nel/sh.tangled.feed.star/s1"); + assert_eq!(body["uri"], "at://did:plc:nel/org.tangled.feed.star/s1"); let (status, _) = json_response( app.oneshot(list_request( @@ -1545,8 +1545,8 @@ async fn limit_below_min_or_above_max_is_400() { async fn count_after_remove_source_returns_zero() { let h = Harness::new().await; let subject = at("at://did:plc:abalone"); - let source = at("at://did:plc:nel/sh.tangled.feed.star/s1"); - h.add_edge(&nsid("sh.tangled.feed.star"), &subject, &source); + let source = at("at://did:plc:nel/org.tangled.feed.star/s1"); + h.add_edge(&nsid("org.tangled.feed.star"), &subject, &source); h.edges.remove_source(&source); let app = router(h.state.clone()); @@ -1618,13 +1618,13 @@ async fn list_item_cid_is_present() { let subject = at("at://did:plc:abalone"); let nel = did("did:plc:nel"); h.add_edge( - &nsid("sh.tangled.feed.star"), + &nsid("org.tangled.feed.star"), &subject, - &at(&format!("at://{}/sh.tangled.feed.star/s1", nel.as_ref())), + &at(&format!("at://{}/org.tangled.feed.star/s1", nel.as_ref())), ); h.mount( &nel, - &nsid("sh.tangled.feed.star"), + &nsid("org.tangled.feed.star"), &rkey("s1"), star_body(&did("did:plc:abalone")), ) @@ -1743,16 +1743,16 @@ async fn list_item_404_dropped_not_404_for_subject() { async fn list_item_with_wrong_type_tag_dropped() { let h = Harness::new().await; let subject = at("at://did:plc:squid"); - let kind = nsid("sh.tangled.feed.star"); + let kind = nsid("org.tangled.feed.star"); h.add_edge( &kind, &subject, - &at("at://did:plc:nel/sh.tangled.feed.star/good"), + &at("at://did:plc:nel/org.tangled.feed.star/good"), ); h.add_edge( &kind, &subject, - &at("at://did:plc:teq/sh.tangled.feed.star/wrong"), + &at("at://did:plc:teq/org.tangled.feed.star/wrong"), ); h.mount( &did("did:plc:nel"), @@ -1764,10 +1764,10 @@ async fn list_item_with_wrong_type_tag_dropped() { Mock::given(method("GET")) .and(path("/xrpc/com.atproto.repo.getRecord")) .and(query_param("repo", "did:plc:teq")) - .and(query_param("collection", "sh.tangled.feed.star")) + .and(query_param("collection", "org.tangled.feed.star")) .and(query_param("rkey", "wrong")) .respond_with(ResponseTemplate::new(200).set_body_json(json!({ - "uri": "at://did:plc:teq/sh.tangled.feed.star/wrong", + "uri": "at://did:plc:teq/org.tangled.feed.star/wrong", "cid": CID, "value": { "$type": "sh.tangled.feed.reaction", @@ -1794,7 +1794,7 @@ async fn list_item_with_wrong_type_tag_dropped() { assert_eq!(items.len(), 1, "wrong-type item dropped, valid star kept"); assert_eq!( items[0]["uri"].as_str().unwrap(), - "at://did:plc:nel/sh.tangled.feed.star/good", + "at://did:plc:nel/org.tangled.feed.star/good", ); } @@ -1812,7 +1812,7 @@ async fn list_item_with_mismatched_collection_dropped() { h.add_edge( &kind, &subject, - &at("at://did:plc:teq/sh.tangled.feed.star/whelk"), + &at("at://did:plc:teq/org.tangled.feed.star/whelk"), ); h.mount( &did("did:plc:nel"), @@ -2064,8 +2064,8 @@ async fn star_endpoints_accept_string_subject_form() { async fn list_after_remove_source_returns_empty_items() { let h = Harness::new().await; let subject = at("at://did:plc:abalone"); - let source = at("at://did:plc:nel/sh.tangled.feed.star/s1"); - h.add_edge(&nsid("sh.tangled.feed.star"), &subject, &source); + let source = at("at://did:plc:nel/org.tangled.feed.star/s1"); + h.add_edge(&nsid("org.tangled.feed.star"), &subject, &source); h.edges.remove_source(&source); let app = router(h.state.clone()); @@ -2175,20 +2175,20 @@ async fn extractor_to_xrpc_round_trip_for_star() { let source_did = did("did:plc:nel"); let rk = rkey("s1"); let source = at(&format!( - "at://{}/sh.tangled.feed.star/{}", + "at://{}/org.tangled.feed.star/{}", source_did.as_ref(), rk.as_ref() )); let body = star_body(&subject_did); let parsed = - bobbin_types::edges::Record::from_json_value(&nsid("sh.tangled.feed.star"), body.clone()) + bobbin_types::edges::Record::from_json_value(&nsid("org.tangled.feed.star"), body.clone()) .expect("parse star record"); parsed .extract_edges(&source) .expect("extract") .into_iter() .for_each(|e| h.edges.add(e)); - h.mount(&source_did, &nsid("sh.tangled.feed.star"), &rk, body) + h.mount(&source_did, &nsid("org.tangled.feed.star"), &rk, body) .await; let app = router(h.state.clone()); @@ -2210,7 +2210,7 @@ async fn extractor_to_xrpc_round_trip_for_star() { let items = json["items"].as_array().unwrap(); assert_eq!(items.len(), 1, "expected exactly one star edge"); assert_eq!( - items[0]["value"]["subject"]["did"], + items[0]["value"]["subject"]["identity"], json!(subject_did.as_ref()) ); } diff --git a/bobbin/crates/xrpc/tests/await_record.rs b/bobbin/crates/xrpc/tests/await_record.rs index ea0c8a6a1..1d637fb83 100644 --- a/bobbin/crates/xrpc/tests/await_record.rs +++ b/bobbin/crates/xrpc/tests/await_record.rs @@ -19,7 +19,7 @@ use tower::ServiceExt; use url::Url; use wiremock::MockServer; -const STAR: &str = "at://did:plc:alice/sh.tangled.feed.star/3l"; +const STAR: &str = "at://did:plc:alice/org.tangled.feed.star/3l"; const SUBSCRIPTION: &str = "at://did:plc:alice/org.tangled.feed.subscription/3l"; const CID: &str = "bafyreieqygohnz2zqyvtvktbjpvhutphobcmbsnt4q5lc36ri7vpcmoz4i"; @@ -231,7 +231,9 @@ async fn a_uri_without_a_collection_fails_fast() { #[tokio::test(start_paused = true)] async fn a_uri_without_an_rkey_fails_fast() { let h = Harness::new().await; - let (status, body) = h.ask("at://did:plc:alice/sh.tangled.feed.star", None).await; + let (status, body) = h + .ask("at://did:plc:alice/org.tangled.feed.star", None) + .await; assert_eq!(status, StatusCode::BAD_REQUEST); assert_eq!(body["error"], "InvalidRequest"); } @@ -241,7 +243,7 @@ async fn a_uri_without_an_rkey_fails_fast() { async fn a_handle_authority_fails_fast() { let h = Harness::new().await; let (status, body) = h - .ask("at://alice.example/sh.tangled.feed.star/3l", None) + .ask("at://alice.example/org.tangled.feed.star/3l", None) .await; assert_eq!(status, StatusCode::BAD_REQUEST); assert_eq!(body["error"], "InvalidRequest"); diff --git a/bobbin/crates/xrpc/tests/await_record_e2e.rs b/bobbin/crates/xrpc/tests/await_record_e2e.rs index 4cdedfc03..a3893ecd5 100644 --- a/bobbin/crates/xrpc/tests/await_record_e2e.rs +++ b/bobbin/crates/xrpc/tests/await_record_e2e.rs @@ -28,7 +28,7 @@ use url::Url; use wiremock::MockServer; const CID: &str = "bafyreieqygohnz2zqyvtvktbjpvhutphobcmbsnt4q5lc36ri7vpcmoz4i"; -const STAR: &str = "at://did:plc:woof/sh.tangled.feed.star/abcabcabcabcz"; +const STAR: &str = "at://did:plc:woof/org.tangled.feed.star/abcabcabcabcz"; struct Hydrant { frames: Vec, @@ -59,14 +59,17 @@ fn star_frame() -> String { "live": true, "did": "did:plc:woof", "rev": "3lzzzzzzzzz2a", - "collection": "sh.tangled.feed.star", + "collection": "org.tangled.feed.star", "rkey": "abcabcabcabcz", "action": "create", "cid": CID, "record": { - "$type": "sh.tangled.feed.star", + "$type": "org.tangled.feed.star", "createdAt": "2026-05-01T00:00:00Z", - "subject": "at://did:plc:meow/sh.tangled.repo/reporkeyabcde", + "subject": { + "$type": "org.tangled.feed.star#record", + "record": { "uri": "at://did:plc:meow/sh.tangled.repo/reporkeyabcde", "cid": CID }, + }, } } }) diff --git a/bobbin/crates/xrpc/tests/enrich.rs b/bobbin/crates/xrpc/tests/enrich.rs index b55177e1b..c6f7c9ea5 100644 --- a/bobbin/crates/xrpc/tests/enrich.rs +++ b/bobbin/crates/xrpc/tests/enrich.rs @@ -153,9 +153,9 @@ async fn repo_fixture(h: &Harness, owner: &Did, repo_did: &Did