From 884ba4b2e9ccdb7ac541ce479140fda33c2f4604 Mon Sep 17 00:00:00 2001
From: Will Pfleger <pfleger.will@gmail.com>
Date: Mon, 27 Jul 2026 14:07:05 -0400
Subject: [PATCH] Revert "fix(cli,relay): resolve agents by verified owner
 (#2615)"

This reverts commit c3084b36d975259f2dfeee8edc9131b40a8bce83.
---
 crates/buzz-cli/README.md                    |   1 -
 crates/buzz-cli/src/commands/users.rs        | 101 +-----
 crates/buzz-cli/src/lib.rs                   |   3 -
 crates/buzz-db/src/lib.rs                    |  18 -
 crates/buzz-db/src/migration.rs              |   2 +-
 crates/buzz-db/src/user.rs                   | 121 -------
 crates/buzz-relay/src/api/bridge.rs          | 328 +------------------
 migrations/0025_users_agent_owner_lookup.sql |   3 -
 8 files changed, 9 insertions(+), 568 deletions(-)
 delete mode 100644 migrations/0025_users_agent_owner_lookup.sql

diff --git a/crates/buzz-cli/README.md b/crates/buzz-cli/README.md
index f5ab0135c3..a8c668cf06 100644
--- a/crates/buzz-cli/README.md
+++ b/crates/buzz-cli/README.md
@@ -56,7 +56,6 @@ buzz reactions get --event <event-id>
 buzz users get                          # your own profile
 buzz users get --pubkey <hex>           # single user
 buzz users get --pubkey <hex> --pubkey <hex>  # batch (max 200)
-buzz users get --name Honey --owner me  # exact-name lookup scoped to your verified owner
 buzz users set-presence --status online
 
 # DMs
diff --git a/crates/buzz-cli/src/commands/users.rs b/crates/buzz-cli/src/commands/users.rs
index 2d36929b8d..3f8325b4b9 100644
--- a/crates/buzz-cli/src/commands/users.rs
+++ b/crates/buzz-cli/src/commands/users.rs
@@ -1,5 +1,3 @@
-use nostr::PublicKey;
-
 use crate::client::{normalize_write_response, BuzzClient};
 use crate::error::CliError;
 use crate::validate::validate_hex64;
@@ -15,7 +13,6 @@ pub async fn cmd_get_users(
     client: &BuzzClient,
     pubkeys: &[String],
     name: Option<&str>,
-    owner: Option<&str>,
     format: &crate::OutputFormat,
 ) -> Result<(), CliError> {
     if let Some(query) = name {
@@ -24,7 +21,7 @@ pub async fn cmd_get_users(
                 "--name and --pubkey are mutually exclusive".into(),
             ));
         }
-        return search_by_name(client, query, owner, format).await;
+        return search_by_name(client, query, format).await;
     }
 
     for pk in pubkeys {
@@ -41,18 +38,12 @@ pub async fn cmd_get_users(
         pubkeys.iter().map(|s| s.as_str()).collect()
     };
 
-    let owner = resolve_owner(client, owner)?;
     let filter = serde_json::json!({
         "kinds": [0],
         "authors": authors,
-        "limit": authors.len(),
-        "include_agent_owner": true,
-        "agent_owner": owner,
+        "limit": authors.len()
     });
     let resp = client.query(&filter).await?;
-    let my_owner_pubkey = client
-        .auth_tag_owner_hex()
-        .unwrap_or_else(|| client.keys().public_key().to_hex());
     let events: Vec<serde_json::Value> = serde_json::from_str(&resp).unwrap_or_default();
     let profiles: Vec<serde_json::Value> = events
         .iter()
@@ -64,7 +55,6 @@ pub async fn cmd_get_users(
                     "pubkey".to_string(),
                     serde_json::json!(e.get("pubkey").and_then(|v| v.as_str()).unwrap_or("")),
                 );
-                copy_owner_fields(e, obj, &my_owner_pubkey);
             }
             Some(profile)
         })
@@ -76,9 +66,6 @@ pub async fn cmd_get_users(
                 .map(|p| serde_json::json!({
                     "pubkey": p.get("pubkey").cloned().unwrap_or_default(),
                     "display_name": p.get("display_name").or_else(|| p.get("name")).cloned().unwrap_or_default(),
-                    "owner_pubkey": p.get("owner_pubkey").cloned().unwrap_or_default(),
-                    "owner_display_name": p.get("owner_display_name").cloned().unwrap_or_default(),
-                    "owned_by_me": p.get("owned_by_me").cloned().unwrap_or_default(),
                 }))
                 .collect();
             serde_json::to_string(&compact).unwrap_or_default()
@@ -89,70 +76,23 @@ pub async fn cmd_get_users(
     Ok(())
 }
 
-fn copy_owner_fields(
-    event: &serde_json::Value,
-    profile: &mut serde_json::Map<String, serde_json::Value>,
-    my_owner_pubkey: &str,
-) {
-    if let Some(value) = event.get("agent_owner_pubkey") {
-        profile.insert("owner_pubkey".to_string(), value.clone());
-    }
-    if let Some(value) = event.get("agent_owner_display_name") {
-        profile.insert("owner_display_name".to_string(), value.clone());
-    }
-    if let Some(owner) = event
-        .get("agent_owner_pubkey")
-        .and_then(|value| value.as_str())
-    {
-        profile.insert(
-            "owned_by_me".to_string(),
-            serde_json::json!(owner == my_owner_pubkey),
-        );
-    }
-}
-
-fn resolve_owner(client: &BuzzClient, owner: Option<&str>) -> Result<Option<String>, CliError> {
-    owner
-        .map(|owner| {
-            if owner == "me" {
-                Ok(client
-                    .auth_tag_owner_hex()
-                    .unwrap_or_else(|| client.keys().public_key().to_hex()))
-            } else {
-                PublicKey::parse(owner)
-                    .map(|pubkey| pubkey.to_hex())
-                    .map_err(|e| {
-                        CliError::Usage(format!("--owner must be `me`, a pubkey, or npub: {e}"))
-                    })
-            }
-        })
-        .transpose()
-}
-
 /// Search for users by display name via NIP-50 full-text search on kind:0 profiles.
 /// Returns [] if the relay does not implement NIP-50 search.
 async fn search_by_name(
     client: &BuzzClient,
     query: &str,
-    owner: Option<&str>,
     format: &crate::OutputFormat,
 ) -> Result<(), CliError> {
     if query.trim().is_empty() {
         return Err(CliError::Usage("--name cannot be empty".into()));
     }
 
-    let owner = resolve_owner(client, owner)?;
     let filter = serde_json::json!({
         "kinds": [0],
         "search": query,
-        "limit": 100,
-        "include_agent_owner": true,
-        "agent_owner": owner,
+        "limit": 100
     });
     let raw = client.query(&filter).await?;
-    let my_owner_pubkey = client
-        .auth_tag_owner_hex()
-        .unwrap_or_else(|| client.keys().public_key().to_hex());
 
     // Parse and filter client-side for case-insensitive substring match
     // on display_name or name fields (NIP-50 may return broader matches).
@@ -186,7 +126,6 @@ async fn search_by_name(
                     "pubkey".to_string(),
                     serde_json::json!(event.get("pubkey").and_then(|v| v.as_str()).unwrap_or("")),
                 );
-                copy_owner_fields(event, obj, &my_owner_pubkey);
             }
             Some(profile)
         })
@@ -198,9 +137,6 @@ async fn search_by_name(
                 .map(|p| serde_json::json!({
                     "pubkey": p.get("pubkey").cloned().unwrap_or_default(),
                     "display_name": p.get("display_name").or_else(|| p.get("name")).cloned().unwrap_or_default(),
-                    "owner_pubkey": p.get("owner_pubkey").cloned().unwrap_or_default(),
-                    "owner_display_name": p.get("owner_display_name").cloned().unwrap_or_default(),
-                    "owned_by_me": p.get("owned_by_me").cloned().unwrap_or_default(),
                 }))
                 .collect();
             serde_json::to_string(&compact).unwrap_or_default()
@@ -375,11 +311,9 @@ pub async fn dispatch(
 ) -> Result<(), CliError> {
     use crate::UsersCmd;
     match cmd {
-        UsersCmd::Get {
-            pubkeys,
-            name,
-            owner,
-        } => cmd_get_users(client, &pubkeys, name.as_deref(), owner.as_deref(), format).await,
+        UsersCmd::Get { pubkeys, name } => {
+            cmd_get_users(client, &pubkeys, name.as_deref(), format).await
+        }
         UsersCmd::SetProfile {
             name,
             avatar,
@@ -402,30 +336,9 @@ pub async fn dispatch(
 
 #[cfg(test)]
 mod tests {
-    use super::{copy_owner_fields, presence_subject};
+    use super::presence_subject;
     use serde_json::json;
 
-    #[test]
-    fn copy_owner_fields_marks_authenticated_owner() {
-        let owner = "a".repeat(64);
-        let event = json!({
-            "agent_owner_pubkey": owner,
-            "agent_owner_display_name": "John",
-        });
-        let mut profile = serde_json::Map::new();
-        copy_owner_fields(&event, &mut profile, &"a".repeat(64));
-        assert_eq!(profile["owner_display_name"], "John");
-        assert_eq!(profile["owned_by_me"], true);
-    }
-
-    #[test]
-    fn copy_owner_fields_marks_other_owner() {
-        let event = json!({"agent_owner_pubkey": "a".repeat(64)});
-        let mut profile = serde_json::Map::new();
-        copy_owner_fields(&event, &mut profile, &"b".repeat(64));
-        assert_eq!(profile["owned_by_me"], false);
-    }
-
     #[test]
     fn presence_subject_uses_p_tag() {
         let event = json!({"pubkey": "relay", "tags": [["p", "user"]]});
diff --git a/crates/buzz-cli/src/lib.rs b/crates/buzz-cli/src/lib.rs
index 1571d74e28..6ab81a082d 100644
--- a/crates/buzz-cli/src/lib.rs
+++ b/crates/buzz-cli/src/lib.rs
@@ -808,9 +808,6 @@ pub enum UsersCmd {
         /// Search by display name (case-insensitive substring match)
         #[arg(long = "name")]
         name: Option<String>,
-        /// Filter agents by verified owner (`me`, 64-char hex, or npub)
-        #[arg(long = "owner")]
-        owner: Option<String>,
     },
     /// Update the current identity's profile
     #[command(name = "set-profile")]
diff --git a/crates/buzz-db/src/lib.rs b/crates/buzz-db/src/lib.rs
index 1df6045032..9c63b2e8ab 100644
--- a/crates/buzz-db/src/lib.rs
+++ b/crates/buzz-db/src/lib.rs
@@ -1843,24 +1843,6 @@ impl Db {
         user::search_users(&self.pool, community_id, query, limit).await
     }
 
-    /// Return agent pubkeys whose verified owner matches `owner_pubkey`.
-    pub async fn list_agent_pubkeys_by_owner(
-        &self,
-        community_id: CommunityId,
-        owner_pubkey: &[u8],
-    ) -> Result<Vec<Vec<u8>>> {
-        user::list_agent_pubkeys_by_owner(&self.pool, community_id, owner_pubkey).await
-    }
-
-    /// Fetch verified ownership metadata for the requested agent pubkeys.
-    pub async fn get_agent_owners(
-        &self,
-        community_id: CommunityId,
-        agent_pubkeys: &[Vec<u8>],
-    ) -> Result<Vec<user::AgentOwner>> {
-        user::get_agent_owners(&self.pool, community_id, agent_pubkeys).await
-    }
-
     /// Atomically set agent owner — only if no owner is currently assigned.
     /// Returns Ok(true) if set, Ok(false) if an owner already exists.
     pub async fn set_agent_owner(
diff --git a/crates/buzz-db/src/migration.rs b/crates/buzz-db/src/migration.rs
index 3605ea98dc..1674b0ec4d 100644
--- a/crates/buzz-db/src/migration.rs
+++ b/crates/buzz-db/src/migration.rs
@@ -560,7 +560,7 @@ mod tests {
         let mut migrations: Vec<_> = MIGRATOR.iter().collect();
         migrations.sort_by_key(|migration| migration.version);
 
-        assert_eq!(migrations.len(), 25);
+        assert_eq!(migrations.len(), 24);
         assert_eq!(migrations[0].version, 1);
         assert_eq!(&*migrations[0].description, "initial schema");
         assert!(migrations[0]
diff --git a/crates/buzz-db/src/user.rs b/crates/buzz-db/src/user.rs
index f477c78f76..066fb5f5c0 100644
--- a/crates/buzz-db/src/user.rs
+++ b/crates/buzz-db/src/user.rs
@@ -5,17 +5,6 @@ use buzz_core::CommunityId;
 use sqlx::PgPool;
 use sqlx::Row;
 
-/// Ownership metadata for an agent profile.
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct AgentOwner {
-    /// Raw agent public key.
-    pub agent_pubkey: Vec<u8>,
-    /// Raw owner public key, verified when the agent authenticated via NIP-OA.
-    pub owner_pubkey: Vec<u8>,
-    /// Owner's current display name, when available.
-    pub owner_display_name: Option<String>,
-}
-
 /// A user's profile fields.
 #[derive(Debug, Clone)]
 pub struct UserProfile {
@@ -291,65 +280,6 @@ pub async fn search_users(
         .collect())
 }
 
-/// Return agent pubkeys whose verified owner matches `owner_pubkey`.
-pub async fn list_agent_pubkeys_by_owner(
-    pool: &PgPool,
-    community_id: CommunityId,
-    owner_pubkey: &[u8],
-) -> Result<Vec<Vec<u8>>> {
-    let rows = sqlx::query_scalar::<_, Vec<u8>>(
-        r#"
-        SELECT pubkey
-        FROM users
-        WHERE community_id = $1 AND agent_owner_pubkey = $2
-        "#,
-    )
-    .bind(community_id.as_uuid())
-    .bind(owner_pubkey)
-    .fetch_all(pool)
-    .await?;
-    Ok(rows)
-}
-
-/// Fetch verified ownership metadata for the requested agent pubkeys.
-pub async fn get_agent_owners(
-    pool: &PgPool,
-    community_id: CommunityId,
-    agent_pubkeys: &[Vec<u8>],
-) -> Result<Vec<AgentOwner>> {
-    if agent_pubkeys.is_empty() {
-        return Ok(Vec::new());
-    }
-
-    let rows = sqlx::query_as::<_, (Vec<u8>, Vec<u8>, Option<String>)>(
-        r#"
-        SELECT agent.pubkey, agent.agent_owner_pubkey, owner.display_name
-        FROM users agent
-        LEFT JOIN users owner
-          ON owner.community_id = agent.community_id
-         AND owner.pubkey = agent.agent_owner_pubkey
-        WHERE agent.community_id = $1
-          AND agent.pubkey = ANY($2)
-          AND agent.agent_owner_pubkey IS NOT NULL
-        "#,
-    )
-    .bind(community_id.as_uuid())
-    .bind(agent_pubkeys)
-    .fetch_all(pool)
-    .await?;
-
-    Ok(rows
-        .into_iter()
-        .map(
-            |(agent_pubkey, owner_pubkey, owner_display_name)| AgentOwner {
-                agent_pubkey,
-                owner_pubkey,
-                owner_display_name,
-            },
-        )
-        .collect())
-}
-
 /// Set the owner pubkey for an agent user.
 /// The owner pubkey must already exist in the users table (FK constraint).
 /// Returns an error if the agent pubkey is not found (rows_affected == 0).
@@ -534,57 +464,6 @@ mod tests {
         );
     }
 
-    #[tokio::test]
-    #[ignore = "requires Postgres"]
-    async fn test_agent_owner_queries_are_scoped_and_include_display_name() {
-        let db = setup_db().await;
-        let community = make_community(&db.pool).await;
-        let agent_pk = random_pubkey();
-        let other_agent_pk = random_pubkey();
-        let owner_pk = random_pubkey();
-        let other_owner_pk = random_pubkey();
-        for pubkey in [&agent_pk, &other_agent_pk, &owner_pk, &other_owner_pk] {
-            ensure_user(&db.pool, community, pubkey).await.unwrap();
-        }
-        update_user_profile(
-            &db.pool,
-            community,
-            &owner_pk,
-            Some("Owner Name"),
-            None,
-            None,
-            None,
-        )
-        .await
-        .unwrap();
-        set_agent_owner(&db.pool, community, &agent_pk, &owner_pk)
-            .await
-            .unwrap();
-        set_agent_owner(&db.pool, community, &other_agent_pk, &other_owner_pk)
-            .await
-            .unwrap();
-
-        assert_eq!(
-            list_agent_pubkeys_by_owner(&db.pool, community, &owner_pk)
-                .await
-                .unwrap(),
-            vec![agent_pk.clone()]
-        );
-        assert_eq!(
-            get_agent_owners(&db.pool, community, &[agent_pk.clone(), other_agent_pk],)
-                .await
-                .unwrap()
-                .into_iter()
-                .find(|owner| owner.agent_pubkey == agent_pk)
-                .unwrap(),
-            AgentOwner {
-                agent_pubkey: agent_pk,
-                owner_pubkey: owner_pk,
-                owner_display_name: Some("Owner Name".into()),
-            }
-        );
-    }
-
     /// set_channel_add_policy should persist each of the three valid policies.
     #[tokio::test]
     #[ignore = "requires Postgres"]
diff --git a/crates/buzz-relay/src/api/bridge.rs b/crates/buzz-relay/src/api/bridge.rs
index 9cfa878d46..c8ec0cdbc9 100644
--- a/crates/buzz-relay/src/api/bridge.rs
+++ b/crates/buzz-relay/src/api/bridge.rs
@@ -280,112 +280,6 @@ fn extension_flag(raw: &Value, key: &str) -> bool {
     raw.get(key).and_then(Value::as_bool).unwrap_or(false)
 }
 
-fn extract_agent_owner(raw: &Value) -> Result<Option<Vec<u8>>, (StatusCode, Json<Value>)> {
-    let Some(value) = raw.get("agent_owner") else {
-        return Ok(None);
-    };
-    if value.is_null() {
-        return Ok(None);
-    }
-    let owner = value.as_str().ok_or_else(|| {
-        api_error(
-            StatusCode::BAD_REQUEST,
-            "agent_owner must be a 64-char hex pubkey",
-        )
-    })?;
-    let bytes = hex::decode(owner)
-        .ok()
-        .filter(|bytes| bytes.len() == 32)
-        .ok_or_else(|| {
-            api_error(
-                StatusCode::BAD_REQUEST,
-                "agent_owner must be a 64-char hex pubkey",
-            )
-        })?;
-    Ok(Some(bytes))
-}
-
-fn include_agent_owner(raw_filters: &[Value]) -> bool {
-    raw_filters
-        .iter()
-        .any(|raw| extension_flag(raw, "include_agent_owner"))
-}
-
-fn apply_agent_owner_authors(raw: &mut Value, owned_pubkeys: &[Vec<u8>]) {
-    let mut owned_hex: std::collections::HashSet<String> =
-        owned_pubkeys.iter().map(hex::encode).collect();
-    if let Some(requested) = raw.get("authors").and_then(Value::as_array) {
-        let requested: std::collections::HashSet<&str> =
-            requested.iter().filter_map(Value::as_str).collect();
-        owned_hex.retain(|pubkey| requested.contains(pubkey.as_str()));
-    }
-    raw["authors"] = Value::Array(owned_hex.into_iter().map(Value::String).collect());
-}
-
-fn reject_unsupported_agent_owner_filter(raw: &Value) -> Result<(), (StatusCode, Json<Value>)> {
-    if raw.get("agent_owner").is_some()
-        && (extension_flag(raw, "top_level")
-            || raw.get("feed_types").is_some()
-            || raw.get("depth_limit").is_some())
-    {
-        return Err(api_error(
-            StatusCode::BAD_REQUEST,
-            "agent_owner is not supported with channel-window, feed, or thread filters",
-        ));
-    }
-    Ok(())
-}
-
-async fn enrich_agent_owners(
-    state: &AppState,
-    tenant: &buzz_core::tenant::TenantContext,
-    events: &mut [Value],
-) -> Result<(), (StatusCode, Json<Value>)> {
-    let pubkeys: Vec<Vec<u8>> = events
-        .iter()
-        .filter_map(|event| event.get("pubkey").and_then(Value::as_str))
-        .filter_map(|pubkey| hex::decode(pubkey).ok())
-        .collect();
-    let owners = state
-        .db
-        .get_agent_owners(tenant.community(), &pubkeys)
-        .await
-        .map_err(|e| internal_error(&format!("agent owner lookup error: {e}")))?;
-    let owners: std::collections::HashMap<Vec<u8>, buzz_db::user::AgentOwner> = owners
-        .into_iter()
-        .map(|owner| (owner.agent_pubkey.clone(), owner))
-        .collect();
-
-    for event in events {
-        let Some(agent_pubkey) = event
-            .get("pubkey")
-            .and_then(Value::as_str)
-            .and_then(|pubkey| hex::decode(pubkey).ok())
-        else {
-            continue;
-        };
-        let Some(owner) = owners.get(&agent_pubkey) else {
-            continue;
-        };
-        let Some(object) = event.as_object_mut() else {
-            continue;
-        };
-        object.insert(
-            "agent_owner_pubkey".into(),
-            Value::String(hex::encode(&owner.owner_pubkey)),
-        );
-        object.insert(
-            "agent_owner_display_name".into(),
-            owner
-                .owner_display_name
-                .clone()
-                .map(Value::String)
-                .unwrap_or(Value::Null),
-        );
-    }
-    Ok(())
-}
-
 fn extract_depth_limit(raw: &Value) -> Option<u32> {
     raw.get("depth_limit")?
         .as_u64()
@@ -1073,20 +967,8 @@ async fn query_events_authed(
 
     // Two-pass parse: preserve raw JSON for custom extension fields (before_id,
     // depth_limit, feed_types) that nostr::Filter silently drops.
-    let mut raw_filters: Vec<Value> = serde_json::from_slice(body)
+    let raw_filters: Vec<Value> = serde_json::from_slice(body)
         .map_err(|e| api_error(StatusCode::BAD_REQUEST, &format!("invalid filters: {e}")))?;
-    for raw in &mut raw_filters {
-        reject_unsupported_agent_owner_filter(raw)?;
-        let Some(owner_pubkey) = extract_agent_owner(raw)? else {
-            continue;
-        };
-        let owned_pubkeys = state
-            .db
-            .list_agent_pubkeys_by_owner(tenant.community(), &owner_pubkey)
-            .await
-            .map_err(|e| internal_error(&format!("agent owner filter error: {e}")))?;
-        apply_agent_owner_authors(raw, &owned_pubkeys);
-    }
     let filters: Vec<nostr::Filter> = raw_filters
         .iter()
         .map(|v| serde_json::from_value(v.clone()))
@@ -1323,14 +1205,6 @@ async fn query_events_authed(
         if handled.contains(&idx) {
             continue;
         }
-        if raw.get("agent_owner").is_some()
-            && raw
-                .get("authors")
-                .and_then(Value::as_array)
-                .is_some_and(Vec::is_empty)
-        {
-            continue;
-        }
 
         if let Some(ch_id) = extract_channel_from_filter(filter) {
             if !accessible_channels.contains(&ch_id) {
@@ -1432,9 +1306,6 @@ async fn query_events_authed(
         }
     }
 
-    if include_agent_owner(&raw_filters) {
-        enrich_agent_owners(state, tenant, &mut events).await?;
-    }
     Ok(Json(Value::Array(events)))
 }
 
@@ -1779,14 +1650,6 @@ async fn handle_bridge_search(
     for (raw, filter) in raw_filters.iter().zip(filters) {
         let search_mode = extract_search_mode(raw);
         let search_page = extract_search_page(raw);
-        if raw.get("agent_owner").is_some()
-            && raw
-                .get("authors")
-                .and_then(Value::as_array)
-                .is_some_and(Vec::is_empty)
-        {
-            continue;
-        }
         let search_text = match &filter.search {
             Some(s) if !s.is_empty() => s.clone(),
             _ => continue,
@@ -1900,9 +1763,6 @@ async fn handle_bridge_search(
         }
     }
 
-    if include_agent_owner(raw_filters) {
-        enrich_agent_owners(state, tenant, &mut events).await?;
-    }
     Ok(Json(Value::Array(events)))
 }
 
@@ -2928,66 +2788,6 @@ mod tests {
         );
     }
 
-    #[test]
-    fn extract_agent_owner_accepts_hex_and_rejects_invalid_values() {
-        let owner = "a".repeat(64);
-        assert_eq!(
-            extract_agent_owner(&serde_json::json!({"agent_owner": owner}))
-                .unwrap()
-                .unwrap(),
-            vec![0xaa; 32]
-        );
-        assert!(extract_agent_owner(&serde_json::json!({"agent_owner": "bad"})).is_err());
-        assert!(extract_agent_owner(&serde_json::json!({"agent_owner": true})).is_err());
-        assert!(extract_agent_owner(&serde_json::json!({"agent_owner": 42})).is_err());
-        assert_eq!(
-            extract_agent_owner(&serde_json::json!({"agent_owner": null})).unwrap(),
-            None
-        );
-        assert_eq!(extract_agent_owner(&serde_json::json!({})).unwrap(), None);
-    }
-
-    #[test]
-    fn agent_owner_authors_fail_closed_and_intersect_requested_authors() {
-        let agent_a = vec![0xaa; 32];
-        let agent_b = vec![0xbb; 32];
-        let owned = vec![agent_a.clone(), agent_b];
-
-        let mut unscoped = serde_json::json!({});
-        apply_agent_owner_authors(&mut unscoped, &owned);
-        let authors = unscoped["authors"].as_array().unwrap();
-        assert_eq!(authors.len(), 2);
-        assert!(authors.contains(&serde_json::json!(hex::encode(&agent_a))));
-
-        let mut intersected = serde_json::json!({
-            "authors": [hex::encode(&agent_a), "cc".repeat(32)]
-        });
-        apply_agent_owner_authors(&mut intersected, &owned);
-        assert_eq!(
-            intersected["authors"],
-            serde_json::json!([hex::encode(agent_a)])
-        );
-
-        let mut empty = serde_json::json!({"authors": ["cc".repeat(32)]});
-        apply_agent_owner_authors(&mut empty, &owned);
-        assert_eq!(empty["authors"], serde_json::json!([]));
-    }
-
-    #[test]
-    fn agent_owner_rejects_specialized_filters_that_cannot_enforce_authors() {
-        for raw in [
-            serde_json::json!({"agent_owner": "aa".repeat(32), "top_level": true}),
-            serde_json::json!({"agent_owner": "aa".repeat(32), "feed_types": ["activity"]}),
-            serde_json::json!({"agent_owner": "aa".repeat(32), "depth_limit": 1}),
-        ] {
-            assert!(reject_unsupported_agent_owner_filter(&raw).is_err());
-        }
-        assert!(reject_unsupported_agent_owner_filter(
-            &serde_json::json!({"agent_owner": "aa".repeat(32), "kinds": [0]})
-        )
-        .is_ok());
-    }
-
     /// `nip42_expected_relay_url` derives scheme from `config_relay_url`'s
     /// prefix: `wss://` → `wss`, everything else → `ws`. Deployments that run
     /// `ws://` in dev/test must produce a `ws://` URL that matches what
@@ -3555,36 +3355,6 @@ mod tests {
 
     /// Drive a single POST /events request through the router and return the
     /// HTTP status code.
-    async fn post_query(
-        state: Arc<crate::state::AppState>,
-        host: &str,
-        pubkey_hex: &str,
-        body: &[u8],
-    ) -> (axum::http::StatusCode, Value) {
-        use axum::body::{to_bytes, Body};
-        use axum::http::{header, Request};
-        use tower::ServiceExt;
-
-        let response = crate::router::build_router(state)
-            .oneshot(
-                Request::builder()
-                    .method("POST")
-                    .uri("/query")
-                    .header(header::HOST, host)
-                    .header("x-pubkey", pubkey_hex)
-                    .body(Body::from(body.to_vec()))
-                    .expect("build request"),
-            )
-            .await
-            .expect("router oneshot");
-        let status = response.status();
-        let bytes = to_bytes(response.into_body(), usize::MAX)
-            .await
-            .expect("read response body");
-        let body = serde_json::from_slice(&bytes).expect("parse response JSON");
-        (status, body)
-    }
-
     async fn post_events(
         state: Arc<crate::state::AppState>,
         host: &str,
@@ -3610,102 +3380,6 @@ mod tests {
             .status()
     }
 
-    #[tokio::test]
-    #[ignore = "requires Postgres and Redis"]
-    async fn query_agent_owner_returns_only_verified_owner_matches() {
-        let state = bridge_handler_test_state()
-            .await
-            .expect("local Postgres and Redis required");
-        let host = format!("bridge-owner-{}.local", uuid::Uuid::new_v4().simple());
-        let community = state
-            .db
-            .ensure_configured_community(&host)
-            .await
-            .expect("ensure community")
-            .id;
-        let requester = Keys::generate();
-        let owner_a = Keys::generate();
-        let owner_b = Keys::generate();
-        let agent_a = Keys::generate();
-        let agent_b = Keys::generate();
-
-        for keys in [&requester, &owner_a, &owner_b, &agent_a, &agent_b] {
-            state
-                .db
-                .ensure_user(community, &keys.public_key().to_bytes())
-                .await
-                .expect("ensure user");
-        }
-        state
-            .db
-            .set_agent_owner(
-                community,
-                &agent_a.public_key().to_bytes(),
-                &owner_a.public_key().to_bytes(),
-            )
-            .await
-            .expect("set first owner");
-        state
-            .db
-            .set_agent_owner(
-                community,
-                &agent_b.public_key().to_bytes(),
-                &owner_b.public_key().to_bytes(),
-            )
-            .await
-            .expect("set second owner");
-
-        for keys in [&agent_a, &agent_b] {
-            let event = EventBuilder::new(Kind::Metadata, r#"{"display_name":"Honey"}"#)
-                .sign_with_keys(keys)
-                .expect("sign profile");
-            state
-                .db
-                .insert_event(community, &event, None)
-                .await
-                .expect("insert profile");
-        }
-
-        let filter = serde_json::json!([{
-            "kinds": [0],
-            "search": "Honey",
-            "agent_owner": owner_a.public_key().to_hex(),
-            "include_agent_owner": true,
-            "limit": 100
-        }]);
-        let (status, body) = post_query(
-            state.clone(),
-            &host,
-            &requester.public_key().to_hex(),
-            filter.to_string().as_bytes(),
-        )
-        .await;
-        assert_eq!(status, StatusCode::OK, "query response: {body}");
-        let results = body.as_array().expect("array response");
-        assert_eq!(results.len(), 1);
-        assert_eq!(results[0]["pubkey"], agent_a.public_key().to_hex());
-        assert_eq!(
-            results[0]["agent_owner_pubkey"],
-            owner_a.public_key().to_hex()
-        );
-
-        let no_match = serde_json::json!([{
-            "kinds": [0],
-            "search": "Honey",
-            "agent_owner": requester.public_key().to_hex(),
-            "limit": 100
-        }]);
-        let (status, body) = post_query(
-            state,
-            &host,
-            &requester.public_key().to_hex(),
-            no_match.to_string().as_bytes(),
-        )
-        .await;
-        assert_eq!(status, StatusCode::OK, "query response: {body}");
-        assert_eq!(body, serde_json::json!([]));
-    }
-
     /// Collect buzz_events_rejected_total with (transport, reason) labels from
     /// a DebuggingRecorder snapshot.
     fn http_reject_counts(
diff --git a/migrations/0025_users_agent_owner_lookup.sql b/migrations/0025_users_agent_owner_lookup.sql
deleted file mode 100644
index 1a55e49e03..0000000000
--- a/migrations/0025_users_agent_owner_lookup.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-CREATE INDEX idx_users_agent_owner
-    ON users (community_id, agent_owner_pubkey)
-    WHERE agent_owner_pubkey IS NOT NULL;
