Format docs
This commit is contained in:
@@ -29,7 +29,8 @@ Identifies the exact place the media depicts using an external identifier (as de
|
|||||||
```json
|
```json
|
||||||
["i", "osm:node:123456"]
|
["i", "osm:node:123456"]
|
||||||
```
|
```
|
||||||
* For OSM POIs, `<type>` MUST be one of: `node`, `way`, `relation`.
|
|
||||||
|
- For OSM POIs, `<type>` MUST be one of: `node`, `way`, `relation`.
|
||||||
|
|
||||||
#### 2. `g` — Geohash
|
#### 2. `g` — Geohash
|
||||||
|
|
||||||
@@ -61,9 +62,9 @@ Clients SHOULD include `alt` (accessibility descriptions), `dim` (dimensions), `
|
|||||||
|
|
||||||
### Optional Tags
|
### Optional Tags
|
||||||
|
|
||||||
* `t`: Hashtags for categorization (e.g., `["t", "food"]`, `["t", "architecture"]`).
|
- `t`: Hashtags for categorization (e.g., `["t", "food"]`, `["t", "architecture"]`).
|
||||||
* `content-warning`: If the media contains NSFW or sensitive imagery.
|
- `content-warning`: If the media contains NSFW or sensitive imagery.
|
||||||
* `published_at`: Unix timestamp of when the photo was originally taken or published.
|
- `published_at`: Unix timestamp of when the photo was originally taken or published.
|
||||||
|
|
||||||
## Example Event
|
## Example Event
|
||||||
|
|
||||||
@@ -80,7 +81,8 @@ Clients SHOULD include `alt` (accessibility descriptions), `dim` (dimensions), `
|
|||||||
["g", "xn0m7h"],
|
["g", "xn0m7h"],
|
||||||
["g", "xn0m7hwq"],
|
["g", "xn0m7hwq"],
|
||||||
|
|
||||||
["imeta",
|
[
|
||||||
|
"imeta",
|
||||||
"url https://example.com/ramen.jpg",
|
"url https://example.com/ramen.jpg",
|
||||||
"m image/jpeg",
|
"m image/jpeg",
|
||||||
"dim 1080x1080",
|
"dim 1080x1080",
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ This NIP defines a standardized event format for decentralized place reviews usi
|
|||||||
|
|
||||||
The design prioritizes:
|
The design prioritizes:
|
||||||
|
|
||||||
* Small event size
|
- Small event size
|
||||||
* Interoperability across clients
|
- Interoperability across clients
|
||||||
* Flexibility for different place types
|
- Flexibility for different place types
|
||||||
* Efficient geospatial querying using geohashes
|
- Efficient geospatial querying using geohashes
|
||||||
|
|
||||||
## Event Kind
|
## Event Kind
|
||||||
|
|
||||||
@@ -23,8 +23,8 @@ Additional tags MAY be included by clients but are not defined by this specifica
|
|||||||
|
|
||||||
This NIP reuses and builds upon existing Nostr tag conventions:
|
This NIP reuses and builds upon existing Nostr tag conventions:
|
||||||
|
|
||||||
* `i` tag: see NIP-73 (External Content Identifiers)
|
- `i` tag: see NIP-73 (External Content Identifiers)
|
||||||
* `g` tag: geohash-based geotagging (community conventions)
|
- `g` tag: geohash-based geotagging (community conventions)
|
||||||
|
|
||||||
Where conflicts arise, this NIP specifies the behavior for review events.
|
Where conflicts arise, this NIP specifies the behavior for review events.
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ Identifies the reviewed place using an external identifier. OpenStreetMap data i
|
|||||||
|
|
||||||
Requirements:
|
Requirements:
|
||||||
|
|
||||||
* For OSM POIs, `<type>` MUST be one of: `node`, `way`, `relation`
|
- For OSM POIs, `<type>` MUST be one of: `node`, `way`, `relation`
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
@@ -57,15 +57,15 @@ Geohash tags are used for spatial indexing and discovery.
|
|||||||
|
|
||||||
##### Requirements
|
##### Requirements
|
||||||
|
|
||||||
* Clients MUST include at least one high-precision geohash (length ≥ 9)
|
- Clients MUST include at least one high-precision geohash (length ≥ 9)
|
||||||
|
|
||||||
##### Recommendations
|
##### Recommendations
|
||||||
|
|
||||||
Clients SHOULD include geohashes at the following resolutions:
|
Clients SHOULD include geohashes at the following resolutions:
|
||||||
|
|
||||||
* length 4 — coarse (city-scale discovery)
|
- length 4 — coarse (city-scale discovery)
|
||||||
* length 6 — medium (default query level, ~1 km)
|
- length 6 — medium (default query level, ~1 km)
|
||||||
* length 7 — fine (neighborhood, ~150 m)
|
- length 7 — fine (neighborhood, ~150 m)
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@@ -80,10 +80,10 @@ Example:
|
|||||||
|
|
||||||
Geospatial queries are performed using the `g` tag.
|
Geospatial queries are performed using the `g` tag.
|
||||||
|
|
||||||
* Clients SHOULD query using a single geohash precision level per request
|
- Clients SHOULD query using a single geohash precision level per request
|
||||||
* Clients MAY include multiple geohash values in a filter to cover a bounding box
|
- Clients MAY include multiple geohash values in a filter to cover a bounding box
|
||||||
* Clients SHOULD limit the number of geohash values per query (e.g. ≤ 30)
|
- Clients SHOULD limit the number of geohash values per query (e.g. ≤ 30)
|
||||||
* Clients MAY reduce precision or split queries when necessary
|
- Clients MAY reduce precision or split queries when necessary
|
||||||
|
|
||||||
Note: Other queries (e.g. fetching reviews for a specific place) are performed using the `i` tag and are outside the scope of geospatial querying.
|
Note: Other queries (e.g. fetching reviews for a specific place) are performed using the `i` tag and are outside the scope of geospatial querying.
|
||||||
|
|
||||||
@@ -228,22 +228,22 @@ The event `content` MUST be valid JSON matching the following schema.
|
|||||||
|
|
||||||
### Ratings
|
### Ratings
|
||||||
|
|
||||||
* Scores are integers from 1 to 10
|
- Scores are integers from 1 to 10
|
||||||
* `quality` is required and represents the core evaluation of the place
|
- `quality` is required and represents the core evaluation of the place
|
||||||
* Other fields are optional and context-dependent
|
- Other fields are optional and context-dependent
|
||||||
|
|
||||||
### Aspects
|
### Aspects
|
||||||
|
|
||||||
* Free-form keys allow domain-specific ratings
|
- Free-form keys allow domain-specific ratings
|
||||||
* Clients MAY define and interpret aspect keys
|
- Clients MAY define and interpret aspect keys
|
||||||
* Clients SHOULD reuse commonly established aspect keys where possible
|
- Clients SHOULD reuse commonly established aspect keys where possible
|
||||||
|
|
||||||
## Recommendation Signal
|
## Recommendation Signal
|
||||||
|
|
||||||
The `recommend` field represents a binary verdict:
|
The `recommend` field represents a binary verdict:
|
||||||
|
|
||||||
* `true` → user recommends the place
|
- `true` → user recommends the place
|
||||||
* `false` → user does not recommend the place
|
- `false` → user does not recommend the place
|
||||||
|
|
||||||
Clients SHOULD strongly encourage users to provide this value.
|
Clients SHOULD strongly encourage users to provide this value.
|
||||||
|
|
||||||
@@ -251,9 +251,9 @@ Clients SHOULD strongly encourage users to provide this value.
|
|||||||
|
|
||||||
Represents user familiarity with the place:
|
Represents user familiarity with the place:
|
||||||
|
|
||||||
* `low` → first visit or limited exposure
|
- `low` → first visit or limited exposure
|
||||||
* `medium` → occasional visits
|
- `medium` → occasional visits
|
||||||
* `high` → frequent or expert-level familiarity
|
- `high` → frequent or expert-level familiarity
|
||||||
|
|
||||||
Clients MAY use this signal for weighting during aggregation.
|
Clients MAY use this signal for weighting during aggregation.
|
||||||
|
|
||||||
@@ -261,16 +261,16 @@ Clients MAY use this signal for weighting during aggregation.
|
|||||||
|
|
||||||
Optional metadata about the visit.
|
Optional metadata about the visit.
|
||||||
|
|
||||||
* `visited_at` is a Unix timestamp
|
- `visited_at` is a Unix timestamp
|
||||||
* `duration_minutes` represents time spent
|
- `duration_minutes` represents time spent
|
||||||
* `party_size` indicates group size
|
- `party_size` indicates group size
|
||||||
|
|
||||||
## Interoperability
|
## Interoperability
|
||||||
|
|
||||||
This specification defines a content payload only.
|
This specification defines a content payload only.
|
||||||
|
|
||||||
* In Nostr: place identity is conveyed via tags
|
- In Nostr: place identity is conveyed via tags
|
||||||
* In other protocols (e.g. ActivityPub, AT Protocol): identity MUST be mapped to the equivalent field (e.g. `object`)
|
- In other protocols (e.g. ActivityPub, AT Protocol): identity MUST be mapped to the equivalent field (e.g. `object`)
|
||||||
|
|
||||||
Content payloads SHOULD NOT include place identifiers.
|
Content payloads SHOULD NOT include place identifiers.
|
||||||
|
|
||||||
@@ -296,18 +296,18 @@ Provides a human-friendly proxy for confidence without requiring numeric input.
|
|||||||
|
|
||||||
Multiple resolutions balance:
|
Multiple resolutions balance:
|
||||||
|
|
||||||
* efficient querying
|
- efficient querying
|
||||||
* small event size
|
- small event size
|
||||||
* early-stage discoverability
|
- early-stage discoverability
|
||||||
|
|
||||||
## Future Work
|
## Future Work
|
||||||
|
|
||||||
* Standardized aspect vocabularies
|
- Standardized aspect vocabularies
|
||||||
* Reputation and weighting models
|
- Reputation and weighting models
|
||||||
* Indexing/aggregation services
|
- Indexing/aggregation services
|
||||||
* Cross-protocol mappings
|
- Cross-protocol mappings
|
||||||
|
|
||||||
## Security Considerations
|
## Security Considerations
|
||||||
|
|
||||||
* Clients SHOULD validate all input
|
- Clients SHOULD validate all input
|
||||||
* Malicious or spam reviews may require external moderation or reputation systems
|
- Malicious or spam reviews may require external moderation or reputation systems
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
Your inputs:
|
Your inputs:
|
||||||
|
|
||||||
* many users
|
- many users
|
||||||
* partial ratings
|
- partial ratings
|
||||||
* different priorities
|
- different priorities
|
||||||
|
|
||||||
Your output:
|
Your output:
|
||||||
|
|
||||||
> “Best place *for this user right now*”
|
> “Best place _for this user right now_”
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -22,8 +22,8 @@ normalized_score = (score - 1) / 9
|
|||||||
|
|
||||||
Why:
|
Why:
|
||||||
|
|
||||||
* easier math
|
- easier math
|
||||||
* comparable across aspects
|
- comparable across aspects
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -50,8 +50,8 @@ positive_ratio = positive_votes / total_votes
|
|||||||
|
|
||||||
Use something like a **Wilson score interval** (this is key):
|
Use something like a **Wilson score interval** (this is key):
|
||||||
|
|
||||||
* prevents small-sample abuse
|
- prevents small-sample abuse
|
||||||
* avoids “1 review = #1 place”
|
- avoids “1 review = #1 place”
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -102,13 +102,12 @@ final_score = Σ (aspect_score × weight)
|
|||||||
|
|
||||||
Filter reviews before scoring:
|
Filter reviews before scoring:
|
||||||
|
|
||||||
* time-based:
|
- time-based:
|
||||||
|
- “last 6 months”
|
||||||
|
|
||||||
* “last 6 months”
|
- context-based:
|
||||||
* context-based:
|
- lunch vs dinner
|
||||||
|
- solo vs group
|
||||||
* lunch vs dinner
|
|
||||||
* solo vs group
|
|
||||||
|
|
||||||
This is something centralized platforms barely do.
|
This is something centralized platforms barely do.
|
||||||
|
|
||||||
@@ -118,9 +117,9 @@ This is something centralized platforms barely do.
|
|||||||
|
|
||||||
Weight reviews by:
|
Weight reviews by:
|
||||||
|
|
||||||
* consistency
|
- consistency
|
||||||
* similarity to user preferences
|
- similarity to user preferences
|
||||||
* past agreement
|
- past agreement
|
||||||
|
|
||||||
This gives you:
|
This gives you:
|
||||||
|
|
||||||
@@ -142,8 +141,8 @@ This gives you:
|
|||||||
|
|
||||||
### Derived:
|
### Derived:
|
||||||
|
|
||||||
* food → high positive ratio (~100%)
|
- food → high positive ratio (~100%)
|
||||||
* service → low (~33%)
|
- service → low (~33%)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -186,7 +185,7 @@ Let clients compute it.
|
|||||||
|
|
||||||
Most reviews will have:
|
Most reviews will have:
|
||||||
|
|
||||||
* 1–3 aspects only
|
- 1–3 aspects only
|
||||||
|
|
||||||
That’s fine.
|
That’s fine.
|
||||||
|
|
||||||
@@ -206,12 +205,12 @@ weight = e^(-λ × age)
|
|||||||
|
|
||||||
Even in nostr:
|
Even in nostr:
|
||||||
|
|
||||||
* spam will happen
|
- spam will happen
|
||||||
|
|
||||||
Mitigation later:
|
Mitigation later:
|
||||||
|
|
||||||
* require minimum interactions
|
- require minimum interactions
|
||||||
* reputation layers
|
- reputation layers
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -233,19 +232,19 @@ We can design:
|
|||||||
|
|
||||||
### A. Query layer
|
### A. Query layer
|
||||||
|
|
||||||
* how clients fetch & merge nostr reviews efficiently
|
- how clients fetch & merge nostr reviews efficiently
|
||||||
|
|
||||||
### B. Anti-spam / trust model
|
### B. Anti-spam / trust model
|
||||||
|
|
||||||
* web-of-trust
|
- web-of-trust
|
||||||
* staking / reputation
|
- staking / reputation
|
||||||
|
|
||||||
### C. OSM integration details
|
### C. OSM integration details
|
||||||
|
|
||||||
* handling duplicates
|
- handling duplicates
|
||||||
* POI identity conflicts
|
- POI identity conflicts
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
If I had to pick one next:
|
If I had to pick one next:
|
||||||
👉 **trust/reputation system** — because without it, everything you built *will* get gamed.
|
👉 **trust/reputation system** — because without it, everything you built _will_ get gamed.
|
||||||
|
|||||||
@@ -2,23 +2,23 @@
|
|||||||
|
|
||||||
## A. Core universal aspects
|
## A. Core universal aspects
|
||||||
|
|
||||||
These should work for *any* place:
|
These should work for _any_ place:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
"quality", // core offering (food, repair, exhibits, etc.)
|
"quality", // core offering (food, repair, exhibits, etc.)
|
||||||
"value", // value for money/time
|
"value", // value for money/time
|
||||||
"experience", // comfort, usability, vibe
|
"experience", // comfort, usability, vibe
|
||||||
"accessibility" // ease of access, inclusivity
|
"accessibility" // ease of access, inclusivity
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Why these work
|
### Why these work
|
||||||
|
|
||||||
* **quality** → your “product” abstraction (critical)
|
- **quality** → your “product” abstraction (critical)
|
||||||
* **value** → universally meaningful signal
|
- **value** → universally meaningful signal
|
||||||
* **experience** → captures everything “soft”
|
- **experience** → captures everything “soft”
|
||||||
* **accessibility** → often ignored but high utility
|
- **accessibility** → often ignored but high utility
|
||||||
|
|
||||||
👉 Resist adding more. Every extra “universal” weakens the concept.
|
👉 Resist adding more. Every extra “universal” weakens the concept.
|
||||||
|
|
||||||
@@ -30,8 +30,8 @@ Not universal, but widely reusable:
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
"service", // human interaction
|
"service", // human interaction
|
||||||
"speed", // waiting time / turnaround
|
"speed", // waiting time / turnaround
|
||||||
"cleanliness",
|
"cleanliness",
|
||||||
"safety",
|
"safety",
|
||||||
"reliability",
|
"reliability",
|
||||||
@@ -41,7 +41,7 @@ Not universal, but widely reusable:
|
|||||||
|
|
||||||
These apply to:
|
These apply to:
|
||||||
|
|
||||||
* restaurants, garages, clinics, parks, etc.
|
- restaurants, garages, clinics, parks, etc.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -69,11 +69,10 @@ Let clients define freely:
|
|||||||
|
|
||||||
To reduce fragmentation:
|
To reduce fragmentation:
|
||||||
|
|
||||||
* publish a **public registry (GitHub repo)**
|
- publish a **public registry (GitHub repo)**
|
||||||
* clients can:
|
- clients can:
|
||||||
|
- suggest additions
|
||||||
* suggest additions
|
- map synonyms
|
||||||
* map synonyms
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -96,6 +95,6 @@ Not required, but useful for aggregation engines.
|
|||||||
|
|
||||||
Map familiarity in UI to:
|
Map familiarity in UI to:
|
||||||
|
|
||||||
* high: “I know this place well”
|
- high: “I know this place well”
|
||||||
* medium: “Been a few times”
|
- medium: “Been a few times”
|
||||||
* low: “First visit”
|
- low: “First visit”
|
||||||
|
|||||||
Reference in New Issue
Block a user