Severity: WARNING
Problem
Three properties use owl:Thing as their range, which is too generic for proper validation and type checking:
Affected properties:
{
"@id": "nostr:tags",
"rdfs:range": { "@id": "owl:Thing" }
},
{
"@id": "nostr:profile",
"rdfs:range": { "@id": "owl:Thing" }
},
{
"@id": "nostr:follows",
"rdfs:range": { "@id": "owl:Thing" }
}
Why This is Problematic
owl:Thing is the most generic type in OWL - it means "any RDF resource." This provides:
- No structural validation
- No type checking
- No schema documentation value
- No tooling support for data validation
What Should Be Used Instead
Each property has a specific structure in Nostr:
1. tags (Array of Arrays)
"tags": [
["e", "event-id", "relay-url"],
["p", "pubkey-hex"],
["t", "hashtag"]
]
Proposed fix:
{
"@id": "nostr:tags",
"@type": "rdfs:Property",
"rdfs:comment": "Event tags as an array of arrays. Each tag is an array where the first element is the tag type.",
"rdfs:range": { "@id": "nostr:TagArray" }
}
Define nostr:TagArray:
{
"@id": "nostr:TagArray",
"@type": "rdfs:Class",
"rdfs:comment": "An array of tag arrays, where each tag is itself an array of strings",
"rdfs:subClassOf": { "@id": "rdfs:Resource" }
}
2. profile (Kind 0 Event Object)
{
"name": "username",
"about": "bio",
"picture": "https://...",
...
}
Proposed fix:
{
"@id": "nostr:profile",
"@type": "rdfs:Property",
"rdfs:comment": "Profile metadata from a kind 0 event",
"rdfs:range": { "@id": "nostr:ProfileMetadata" }
}
Define nostr:ProfileMetadata:
{
"@id": "nostr:ProfileMetadata",
"@type": "rdfs:Class",
"rdfs:comment": "Structured profile metadata containing name, about, picture, etc.",
"rdfs:subClassOf": { "@id": "rdfs:Resource" }
}
3. follows (Array of Pubkeys)
["pubkey1", "pubkey2", "pubkey3"]
Proposed fix:
{
"@id": "nostr:follows",
"@type": "rdfs:Property",
"rdfs:comment": "Array of pubkey hex strings representing followed accounts (from kind 3 events)",
"rdfs:range": { "@id": "nostr:PubkeyList" }
}
Define nostr:PubkeyList:
{
"@id": "nostr:PubkeyList",
"@type": "rdfs:Class",
"rdfs:comment": "An array of 64-character lowercase hex strings representing Nostr public keys",
"rdfs:subClassOf": { "@id": "rdfs:Resource" }
}
Benefits of Fixing
- Type safety: Validators can check structure
- Documentation: Developers understand expected format
- Tooling: IDEs and validators can provide better support
- Interoperability: Standard RDF tools can reason about types
- Future-proofing: Easier to extend with subclasses
Implementation Notes
If you want to keep it simpler without defining new classes, you could use:
- JSON Schema types (via
@type: "@json" in JSON-LD)
- More specific XSD types (xsd:array if available)
- Or simply better documentation in
rdfs:comment
But defining specific classes is the RDF/OWL best practice.
Priority
MEDIUM-HIGH - Doesn't break functionality but limits schema usefulness for validation and tooling.
Severity: WARNING
Problem
Three properties use
owl:Thingas their range, which is too generic for proper validation and type checking:Affected properties:
{ "@id": "nostr:tags", "rdfs:range": { "@id": "owl:Thing" } }, { "@id": "nostr:profile", "rdfs:range": { "@id": "owl:Thing" } }, { "@id": "nostr:follows", "rdfs:range": { "@id": "owl:Thing" } }Why This is Problematic
owl:Thingis the most generic type in OWL - it means "any RDF resource." This provides:What Should Be Used Instead
Each property has a specific structure in Nostr:
1. tags (Array of Arrays)
Proposed fix:
{ "@id": "nostr:tags", "@type": "rdfs:Property", "rdfs:comment": "Event tags as an array of arrays. Each tag is an array where the first element is the tag type.", "rdfs:range": { "@id": "nostr:TagArray" } }Define
nostr:TagArray:{ "@id": "nostr:TagArray", "@type": "rdfs:Class", "rdfs:comment": "An array of tag arrays, where each tag is itself an array of strings", "rdfs:subClassOf": { "@id": "rdfs:Resource" } }2. profile (Kind 0 Event Object)
{ "name": "username", "about": "bio", "picture": "https://...", ... }Proposed fix:
{ "@id": "nostr:profile", "@type": "rdfs:Property", "rdfs:comment": "Profile metadata from a kind 0 event", "rdfs:range": { "@id": "nostr:ProfileMetadata" } }Define
nostr:ProfileMetadata:{ "@id": "nostr:ProfileMetadata", "@type": "rdfs:Class", "rdfs:comment": "Structured profile metadata containing name, about, picture, etc.", "rdfs:subClassOf": { "@id": "rdfs:Resource" } }3. follows (Array of Pubkeys)
Proposed fix:
{ "@id": "nostr:follows", "@type": "rdfs:Property", "rdfs:comment": "Array of pubkey hex strings representing followed accounts (from kind 3 events)", "rdfs:range": { "@id": "nostr:PubkeyList" } }Define
nostr:PubkeyList:{ "@id": "nostr:PubkeyList", "@type": "rdfs:Class", "rdfs:comment": "An array of 64-character lowercase hex strings representing Nostr public keys", "rdfs:subClassOf": { "@id": "rdfs:Resource" } }Benefits of Fixing
Implementation Notes
If you want to keep it simpler without defining new classes, you could use:
@type: "@json"in JSON-LD)rdfs:commentBut defining specific classes is the RDF/OWL best practice.
Priority
MEDIUM-HIGH - Doesn't break functionality but limits schema usefulness for validation and tooling.