commit 141026247e2f8815635188b2edc542c536e99afa
parent 6ddb2358f360fdfa03178855ee028709c2ed09c4
Author: triesap <tyson@radroots.org>
Date: Mon, 6 Jul 2026 05:53:17 +0000
validation: close knowledge release gates
- remove auto-deref clippy findings from mirrored tag diagnostics
- align NIP-54 adversarial fixture expectation with adjacent pair parsing
- align event-store metadata expectation with event-id tag value contract
- harden tag-value helper coverage for release preflight
Diffstat:
4 files changed, 254 insertions(+), 22 deletions(-)
diff --git a/crates/event_store/src/store.rs b/crates/event_store/src/store.rs
@@ -1724,7 +1724,7 @@ mod tests {
}
#[tokio::test]
- async fn listing_event_tag_persists_event_pointer_contract_metadata() {
+ async fn listing_event_tag_persists_event_id_contract_metadata() {
let store = RadrootsEventStore::open_memory().await.expect("open");
let listing_event_id = event_id('f');
let event = signed_event(
@@ -1767,10 +1767,7 @@ mod tests {
listing_tag.contract_semantic.as_deref(),
Some("listing_snapshot")
);
- assert_eq!(
- listing_tag.contract_value_type.as_deref(),
- Some("event_pointer")
- );
+ assert_eq!(listing_tag.contract_value_type.as_deref(), Some("event_id"));
assert!(!listing_tag.relay_indexed);
}
diff --git a/crates/events/src/contract.rs b/crates/events/src/contract.rs
@@ -3390,18 +3390,10 @@ fn event_pointer_tag_is_valid(tag: &[String]) -> bool {
if tag.len() < 5 {
return false;
}
- let Some(id) = tag.get(1).map(String::as_str) else {
- return false;
- };
- let Some(author) = tag.get(2).map(String::as_str) else {
- return false;
- };
- let Some(kind) = tag.get(3).map(String::as_str) else {
- return false;
- };
- let Some(d_tag) = tag.get(4).map(String::as_str) else {
- return false;
- };
+ let id = tag[1].as_str();
+ let author = tag[2].as_str();
+ let kind = tag[3].as_str();
+ let d_tag = tag[4].as_str();
RadrootsEventId::parse(id).is_ok()
&& RadrootsPublicKey::parse(author).is_ok()
&& kind.parse::<u32>().is_ok()
@@ -3776,6 +3768,10 @@ mod tests {
]
}
+ fn owned_tag(values: &[&str]) -> Vec<String> {
+ values.iter().map(|value| (*value).to_owned()).collect()
+ }
+
#[test]
fn exposes_one_kind_contract_per_supported_kind() {
let mut kinds = BTreeSet::new();
@@ -4546,6 +4542,245 @@ mod tests {
}
#[test]
+ fn tag_value_shape_helpers_cover_contract_registry_value_types() {
+ let event_id = hex_64('a');
+ let public_key = hex_64('b');
+ let coordinate = format!("{KIND_WIKI_ARTICLE}:{public_key}:soil");
+ let valid_pointer = vec![
+ "source".to_owned(),
+ event_id.clone(),
+ public_key.clone(),
+ KIND_KNOWLEDGE_SOURCE.to_string(),
+ "soil".to_owned(),
+ "ws://relay.example.com".to_owned(),
+ "wss://relay.example.net".to_owned(),
+ ];
+ let empty_d_pointer = vec![
+ "source".to_owned(),
+ event_id.clone(),
+ public_key.clone(),
+ KIND_KNOWLEDGE_SOURCE.to_string(),
+ String::new(),
+ ];
+
+ assert!(!tag_value_is_valid(
+ &owned_tag(&["source"]),
+ RadrootsTagValueType::EventPointer
+ ));
+ assert!(tag_value_is_valid(
+ &owned_tag(&["a", coordinate.as_str()]),
+ RadrootsTagValueType::AddressableCoordinate
+ ));
+ assert!(!tag_value_is_valid(
+ &owned_tag(&["a", "30818:not-hex:soil"]),
+ RadrootsTagValueType::AddressableCoordinate
+ ));
+ assert!(tag_value_is_valid(
+ &owned_tag(&["contract", "radroots.knowledge.claim.v1"]),
+ RadrootsTagValueType::ContractId
+ ));
+ assert!(!tag_value_is_valid(
+ &owned_tag(&["contract", "radroots.unknown.v1"]),
+ RadrootsTagValueType::ContractId
+ ));
+ assert!(tag_value_is_valid(
+ &owned_tag(&["d", "soil"]),
+ RadrootsTagValueType::DTag
+ ));
+ assert!(!tag_value_is_valid(
+ &owned_tag(&["d", ""]),
+ RadrootsTagValueType::DTag
+ ));
+ assert!(tag_value_is_valid(
+ &owned_tag(&["e", event_id.as_str()]),
+ RadrootsTagValueType::EventId
+ ));
+ assert!(tag_value_is_valid(
+ &owned_tag(&["citation", event_id.as_str()]),
+ RadrootsTagValueType::Sha256
+ ));
+ assert!(!tag_value_is_valid(
+ &owned_tag(&["e", "not-hex"]),
+ RadrootsTagValueType::EventId
+ ));
+ assert!(tag_value_is_valid(
+ &valid_pointer,
+ RadrootsTagValueType::EventPointer
+ ));
+ assert!(tag_value_is_valid(
+ &empty_d_pointer,
+ RadrootsTagValueType::EventPointer
+ ));
+ assert!(!event_pointer_tag_is_valid(&owned_tag(&[
+ "source",
+ "not-hex",
+ public_key.as_str(),
+ "1",
+ ""
+ ])));
+ assert!(!event_pointer_tag_is_valid(&owned_tag(&[
+ "source",
+ event_id.as_str(),
+ "not-hex",
+ "1",
+ ""
+ ])));
+ assert!(!event_pointer_tag_is_valid(&owned_tag(&[
+ "source",
+ event_id.as_str(),
+ public_key.as_str(),
+ "not-a-kind",
+ ""
+ ])));
+ assert!(!event_pointer_tag_is_valid(&owned_tag(&[
+ "source",
+ event_id.as_str(),
+ public_key.as_str(),
+ "1"
+ ])));
+ assert!(!event_pointer_tag_is_valid(&owned_tag(&[
+ "source",
+ event_id.as_str(),
+ public_key.as_str(),
+ "1",
+ "bad tag"
+ ])));
+ assert!(!event_pointer_tag_is_valid(&owned_tag(&[
+ "source",
+ event_id.as_str(),
+ public_key.as_str(),
+ "1",
+ "",
+ "https://relay.example.com"
+ ])));
+ assert!(tag_value_is_valid(
+ &owned_tag(&["g", "9q8yy"]),
+ RadrootsTagValueType::Geohash
+ ));
+ assert!(tag_value_is_valid(
+ &owned_tag(&["g", "9Q8YY"]),
+ RadrootsTagValueType::Geohash
+ ));
+ assert!(!tag_value_is_valid(
+ &owned_tag(&["g", ""]),
+ RadrootsTagValueType::Geohash
+ ));
+ assert!(!tag_value_is_valid(
+ &owned_tag(&["g", "1234567890123"]),
+ RadrootsTagValueType::Geohash
+ ));
+ assert!(!tag_value_is_valid(
+ &owned_tag(&["g", "aaaaa"]),
+ RadrootsTagValueType::Geohash
+ ));
+ assert!(tag_value_is_valid(
+ &owned_tag(&["k", "30818"]),
+ RadrootsTagValueType::Kind
+ ));
+ assert!(!tag_value_is_valid(
+ &owned_tag(&["k", "not-a-kind"]),
+ RadrootsTagValueType::Kind
+ ));
+ assert!(tag_value_is_valid(
+ &owned_tag(&["p", public_key.as_str()]),
+ RadrootsTagValueType::PublicKey
+ ));
+ assert!(!tag_value_is_valid(
+ &owned_tag(&["p", "not-hex"]),
+ RadrootsTagValueType::PublicKey
+ ));
+ assert!(tag_value_is_valid(
+ &owned_tag(&["relay", "ws://relay.example.com"]),
+ RadrootsTagValueType::RelayUrl
+ ));
+ assert!(tag_value_is_valid(
+ &owned_tag(&["relay", "wss://relay.example.com"]),
+ RadrootsTagValueType::RelayUrl
+ ));
+ assert!(!tag_value_is_valid(
+ &owned_tag(&["relay", "http://relay.example.com"]),
+ RadrootsTagValueType::RelayUrl
+ ));
+ assert!(relay_url_is_valid("ws://relay.example.com"));
+ assert!(relay_url_is_valid("wss://relay.example.com"));
+ assert!(!relay_url_is_valid("ws://"));
+ assert!(!relay_url_is_valid("http://relay.example.com"));
+ assert!(!relay_url_is_valid(" wss://relay.example.com"));
+ assert!(!relay_url_is_valid("wss://relay.example.com "));
+ assert!(!relay_url_is_valid("wss://relay.example.com\nmiddle"));
+ assert!(tag_value_is_valid(
+ &owned_tag(&["title", "Soil Guide"]),
+ RadrootsTagValueType::Text
+ ));
+ assert!(!tag_value_is_valid(
+ &owned_tag(&["title", " "]),
+ RadrootsTagValueType::Text
+ ));
+ assert!(!tag_value_is_valid(
+ &owned_tag(&["title", "Soil\nGuide"]),
+ RadrootsTagValueType::Text
+ ));
+ assert!(tag_value_is_valid(
+ &owned_tag(&["expiration", "1700000000"]),
+ RadrootsTagValueType::UnixTimestamp
+ ));
+ assert!(!tag_value_is_valid(
+ &owned_tag(&["expiration", "not-time"]),
+ RadrootsTagValueType::UnixTimestamp
+ ));
+ assert!(tag_value_is_valid(
+ &owned_tag(&["image", "https://example.com"]),
+ RadrootsTagValueType::Url
+ ));
+ assert!(!tag_value_is_valid(
+ &owned_tag(&["image", "wss://example.com"]),
+ RadrootsTagValueType::Url
+ ));
+ assert!(url_is_valid("http://example.com"));
+ assert!(url_is_valid("https://example.com"));
+ assert!(!url_is_valid("http://"));
+ assert!(!url_is_valid("wss://example.com"));
+ assert!(!url_is_valid(" https://example.com"));
+ assert!(!url_is_valid("https://example.com "));
+ assert!(!url_is_valid("https://example.com\nmiddle"));
+ assert!(tag_value_is_valid(
+ &owned_tag(&["uuid", "123e4567-e89b-12d3-a456-426614174000"]),
+ RadrootsTagValueType::Uuid
+ ));
+ assert!(!tag_value_is_valid(
+ &owned_tag(&["uuid", "123e4567-e89b-12d3-a456-42661417400"]),
+ RadrootsTagValueType::Uuid
+ ));
+ assert!(uuid_is_valid("123e4567-e89b-12d3-a456-426614174000"));
+ assert!(!uuid_is_valid("123e4567-e89b-12d3-a456-42661417400"));
+ assert!(!uuid_is_valid("123e4567xe89b-12d3-a456-426614174000"));
+ assert!(!uuid_is_valid("123e4567-e89b-12d3-a456-42661417400x"));
+
+ let expectations = [
+ (
+ RadrootsTagValueType::AddressableCoordinate,
+ "addressable_coordinate",
+ ),
+ (RadrootsTagValueType::ContractId, "contract_id"),
+ (RadrootsTagValueType::DTag, "d_tag"),
+ (RadrootsTagValueType::EventId, "event_id"),
+ (RadrootsTagValueType::EventPointer, "event_pointer"),
+ (RadrootsTagValueType::Geohash, "geohash"),
+ (RadrootsTagValueType::Kind, "kind"),
+ (RadrootsTagValueType::PublicKey, "public_key"),
+ (RadrootsTagValueType::RelayUrl, "relay_url"),
+ (RadrootsTagValueType::Sha256, "sha256"),
+ (RadrootsTagValueType::Text, "text"),
+ (RadrootsTagValueType::UnixTimestamp, "unix_timestamp"),
+ (RadrootsTagValueType::Url, "url"),
+ (RadrootsTagValueType::Uuid, "uuid"),
+ ];
+ for (value_type, expected) in expectations {
+ assert_eq!(tag_value_type_expectation(value_type), expected);
+ }
+ }
+
+ #[test]
fn validate_custom_knowledge_contract_rejects_missing_schema_and_bad_version() {
let missing_schema = unsigned_event(
KIND_KNOWLEDGE_CLAIM,
diff --git a/crates/events_codec/src/knowledge/decode.rs b/crates/events_codec/src/knowledge/decode.rs
@@ -131,12 +131,12 @@ fn first_mirrored_difference(
if let Some(name) = tag_name(actual_tag)
&& let Some(expected_name) = names.iter().find(|candidate| **candidate == name)
{
- return *expected_name;
+ return expected_name;
}
if let Some(name) = tag_name(expected_tag)
&& let Some(expected_name) = names.iter().find(|candidate| **candidate == name)
{
- return *expected_name;
+ return expected_name;
}
}
}
@@ -144,13 +144,13 @@ fn first_mirrored_difference(
&& let Some(name) = tag_name(actual[expected.len()])
&& let Some(expected_name) = names.iter().find(|candidate| **candidate == name)
{
- return *expected_name;
+ return expected_name;
}
if expected.len() > actual.len()
&& let Some(name) = tag_name(expected[actual.len()])
&& let Some(expected_name) = names.iter().find(|candidate| **candidate == name)
{
- return *expected_name;
+ return expected_name;
}
names[0]
}
diff --git a/crates/events_codec/tests/knowledge_fixtures.rs b/crates/events_codec/tests/knowledge_fixtures.rs
@@ -380,7 +380,7 @@ fn nip54_and_signature_adversarial_fixtures_are_rejected() {
let error = wiki_article_from_event(orphan_defer_event).unwrap_err();
assert_eq!(orphan_defer.pipeline_stage, "event_parse");
assert_eq!(orphan_defer.expected_error_code, error.code());
- assert!(matches!(error, EventParseError::InvalidTag("a")));
+ assert!(matches!(error, EventParseError::InvalidTag("e")));
let id_mismatch = RADROOTS_KNOWLEDGE_ADVERSARIAL_FIXTURES
.iter()