···11+{
22+ "lexicon": 1,
33+ "id": "world.geocache.attribute",
44+ "defs": {
55+ "fee": {
66+ "type": "token",
77+ "description": "This cache requires an entry fee, like a park admission fee."
88+ },
99+ "allAges": {
1010+ "type": "token",
1111+ "description": "This cache is suitable for all ages. It is easy and safe to find, and does not contain NSFW materials."
1212+ },
1313+ "winterFriendly": {
1414+ "type": "token",
1515+ "description": "This cache is accessible during winter."
1616+ },
1717+ "poisonousPlants": {
1818+ "type": "token",
1919+ "description": "This cache is in an area known to have poisonous plants."
2020+ },
2121+ "snakes": {
2222+ "type": "token",
2323+ "description": "This cache is in an area known to have snakes."
2424+ },
2525+ "ticks": {
2626+ "type": "token",
2727+ "description": "This cache is in an area known to have ticks."
2828+ },
2929+ "dangerous": {
3030+ "type": "token",
3131+ "description": "This cache is in an area which poses significant risk of injury or other dangers."
3232+ },
3333+ "accessible": {
3434+ "type": "token",
3535+ "description": "This cache is accessible to people of all abilities."
3636+ },
3737+ "thorns": {
3838+ "type": "token",
3939+ "description": "This cache is in an area known to have thorny plants."
4040+ },
4141+ "flashlight": {
4242+ "type": "token",
4343+ "description": "This cache requires a flashlight to find."
4444+ },
4545+ "bigrig": {
4646+ "type": "token",
4747+ "description": "This cache is in an area accessible to large vehicles, like RVs and trucks."
4848+ },
4949+ "trail": {
5050+ "type": "token",
5151+ "description": "This cache is only accessible through non-paved trails."
5252+ },
5353+ "specialEquipment": {
5454+ "type": "token",
5555+ "description": "This cache needs special equipment to access -- see description of cache."
5656+ },
5757+ "night": {
5858+ "type": "token",
5959+ "description": "This cache is able to be found at night with use of a flashlight, such as with reflective markers."
6060+ },
6161+ "garminChirp": {
6262+ "type": "token",
6363+ "description": "This cache contains a Garmin Chirp device."
6464+ },
6565+ "letterbox": {
6666+ "type": "token",
6767+ "description": "This cache is a letterbox, and contains a stamp the cacher can use to mark their own logbook."
6868+ },
6969+ "compass": {
7070+ "type": "token",
7171+ "description": "This cache requires use of a compass to find."
7272+ },
7373+ "quick": {
7474+ "type": "token",
7575+ "description": "This cache can be found within 15 minutes, including access time from the nearest parking space, transit stop, or trailhead."
7676+ },
7777+ "traveller": {
7878+ "type": "token",
7979+ "description": "This cache is suitable for travellers."
8080+ },
8181+ "byop": {
8282+ "type": "token",
8383+ "description": "This cache does not have a pen for you to use, so the cacher must bring their own."
8484+ },
8585+ "magnetic": {
8686+ "type": "token",
8787+ "description": "This cache is magnetically attached to its resting place."
8888+ },
8989+ "audio": {
9090+ "type": "token",
9191+ "description": "This cache has audio cues available."
9292+ },
9393+ "offset": {
9494+ "type": "token",
9595+ "description": "This cache requires multiple steps in order to find it."
9696+ },
9797+ "usb": {
9898+ "type": "token",
9999+ "description": "This cache contains, or is in its entirety, a USB flashdrive."
100100+ },
101101+ "surveyBenchmark": {
102102+ "type": "token",
103103+ "description": "This cache is, or is near, a survey benchmark."
104104+ },
105105+ "woods": {
106106+ "type": "token",
107107+ "description": "This cache is located in a forested area."
108108+ },
109109+ "historic": {
110110+ "type": "token",
111111+ "description": "This cache is located in or near a site of historic significance."
112112+ },
113113+ "advertisement": {
114114+ "type": "token",
115115+ "description": "This cache contains, or is in of itself, an advertisement for some commercial entity."
116116+ },
117117+ "limitedaccess": {
118118+ "type": "token",
119119+ "description": "This cache has limited access opportunities, including but not limited to: time-of-day limited, seasonally limited."
120120+ },
121121+ "guestBook": {
122122+ "type": "token",
123123+ "description": "This cache is an existing, permanent guestbook open to the public, such as ones located in a visitor center or hotel."
124124+ },
125125+ "challenge": {
126126+ "type": "token",
127127+ "description": "This cache is not suitable for beginner cachers, and may require advanced techniques to find."
128128+ },
129129+ "urban": {
130130+ "type": "token",
131131+ "description": "This cache is located in an urban environment."
132132+ },
133133+ "bikeFriendly": {
134134+ "type": "token",
135135+ "description": "This cache is located in an area accessible by bicycle."
136136+ },
137137+ "keypair": {
138138+ "type": "token",
139139+ "description": "This cache has a public/private keypair that can be used to create a visit signature."
140140+ },
141141+ "noInternet": {
142142+ "type": "token",
143143+ "description": "This cache is located somewhere without reliable, commonly available internet access, such as a public wifi hotspot, or a mobile network."
144144+ },
145145+ "bushwhacking": {
146146+ "type": "token",
147147+ "description": "This cache is located somewhere that does not have an established path or trail of any sort."
148148+ },
149149+ "underwater": {
150150+ "type": "token",
151151+ "description": "This cache is located inside a body of water."
152152+ },
153153+ "cave": {
154154+ "type": "token",
155155+ "description": "This cache is located inside a cave."
156156+ },
157157+ }
158158+}
+237-138
lexicon/world.geocache.experimental.geocache.json
···11{
22 "lexicon": 1,
33 "id": "world.geocache.experimental.geocache",
44- "defs": {
55- "main": {
66- "type": "record",
77- "description": "A geocache out there in the world",
88- "key": "tid",
99- "record": {
1010- "type": "object",
1111- "required": ["name", "location", "cacheType", "status", "attributes", "description", "createdAt"],
1212- "properties": {
1313- "name": {
1414- "type": "string",
1515- "maxLength": 1000,
1616- "maxGraphemes": 100,
1717- "description": "The name for the geocache"
1818- },
1919- "location": {
2020- "type": "object",
2121- "required": ["address", "geo"],
2222- "properties": {
2323- "geo": { "type": "ref", "ref": "community.lexicon.location.geo" },
2424- "address": { "type": "ref", "ref": "community.lexicon.location.address" },
2525- "hthree": { "type": "ref", "ref": "community.lexicon.location.hthree" },
2626- "ip": { "type": "string", "format": "uri"}
2727- }
2828- },
2929- "cacheType": {
3030- "type": "union",
3131- /*
3232- there's a few cache types that opencaching has which i'm not sure about
3333- - moving
3434- this is the most interesting one -- this represents a geocache that is moving
3535- between each find (typically the finder moves the cache, updates the coordinates
3636- after finding it). atproto does not currently have shared records, so you can't
3737- do it that way.
3838-3939- my immediate thought would be: a special subset of the geocache lexicon which
4040- has a parameter for "nextLocation" -- the finder of the cache logs their visit,
4141- not as a traditional "visit" lexicon, but instead as a "movedCache". while this would
4242- introduce friction in that you would need the owner to update the cache, it would
4343- be a pretty simple implementation from then on. the appview would just need to
4444- keep track of successive moves and display them to the user. you'd also get a mostly free
4545- history view, which could be super fun!
4646-4747- if combined with the idea of pubkey verification, you could even automate the transfer
4848- of a geocache -- the appview listens for a visit that has a linkback, verifies that
4949- the signature is properly decrypted, and then would update the record on the original
5050- owner's PDS to point to the first finder...
5151- - event
5252- the way this is described on opencaching seems to just represent like,
5353- an in person meetup or something like that. not sure we need this one.
5454- it would provide some feature pairity to opencaching, at least?
5555- - webcam
5656- these represent geocaches which use a webcam to log visits.
5757- i don't see why this can't just be an attribute of a cache.
5858- */
5959- "refs": [
6060- "world.geocache.type#traditional",
6161- "world.geocache.type#multi",
6262- "world.geocache.type#puzzle",
6363- /* idea: what if a virtual cache type could point to a URI or IP address?
6464- you could create a "virtual geocache" in the spirit of wargames.
44+ "defs": {
55+ "main": {
66+ "type": "record",
77+ "description": "A geocache out there in the world",
88+ "key": "tid",
99+ "record": {
1010+ "type": "object",
1111+ "required": ["name", "location", "cacheType", "status", "attributes", "description", "createdAt"],
1212+ "properties": {
1313+ "name": {
1414+ "type": "string",
1515+ "maxLength": 1000,
1616+ "maxGraphemes": 100,
1717+ "description": "The name for the geocache"
1818+ },
1919+ "location": {
2020+ /* because we want to support many types of geocaches, we don't want
2121+ to force any location type on the cache. generally, most non-digital
2222+ geocaches will have an address and a geo coordinate, whereas
2323+ digital ones will only have a URI
65246666- opencaching uses the virtual type to refer to a cache where the location
6767- itself is the reward, and there is not any physical objects. it might
6868- be worth differentiating these two ideas of "virtual geocaches", if such a thing would
6969- be desired.
2525+ this property can be extended with additional location data for
2626+ whatever niche caches users may wish to create
7027 */
7171- "world.geocache.type#virtual",
7272- "world.geocache.type#owncache", // this could have a less clunky name, imo
7373- "world.geogache.type#other"
7474- ]
7575- },
7676- "status": {
7777- "type": "union",
7878- "description": "The status of the geocache",
7979- // other statuses may be useful
8080- "refs": [
8181- "world.geocache.status#active", // ready to be searched
8282- "world.geocache.status#dead", // no longer accessible, general
8383- "world.geocache.status#done", // no longer accessible, time limited geocaches
8484- "world.geocache.status#moved", // no longer accessible at given location, for moving caches
8585- "world.geocache.status#unknown" // may not be accessible
8686- ]
8787- },
8888- "attributes": {
8989- /*
9090- opencaching has 35 attributes: https://wiki.opencaching.us/index.php/Cache_parameters#Attributes
2828+ "type": "object",
2929+ "properties": {
3030+ "geo": { "type": "ref", "ref": "community.lexicon.location.geo" },
3131+ "address": { "type": "ref", "ref": "community.lexicon.location.address" },
3232+ "hthree": { "type": "ref", "ref": "community.lexicon.location.hthree" },
3333+ "uri": { "type": "string", "format": "uri"}
3434+ }
3535+ },
3636+ "cacheType": {
3737+ "type": "ref",
3838+ "ref": "world.geocache.cache#cacheType"
3939+ },
4040+ "status": {
4141+ "type": "ref",
4242+ "description": "The status of the geocache",
4343+ "ref": "world.geocache.cache#status"
4444+ },
4545+ "attributes": {
4646+ "type": "array",
4747+ "description": "Information about the geocache.",
4848+ "items": {
4949+ "type": "union",
5050+ "refs": [
5151+ "world.geocache.cache.attribute#fee",
5252+ "world.geocache.cache.attribute#allAges",
5353+ "world.geocache.cache.attribute#winterFriendly",
5454+ "world.geocache.cache.attribute#poisonousPlants",
5555+ "world.geocache.cache.attribute#snakes",
5656+ "world.geocache.cache.attribute#ticks",
5757+ "world.geocache.cache.attribute#dangerous",
5858+ "world.geocache.cache.attribute#accessible",
5959+ "world.geocache.cache.attribute#thorns",
6060+ "world.geocache.cache.attribute#flashlight",
6161+ "world.geocache.cache.attribute#bigrig",
6262+ "world.geocache.cache.attribute#trail",
6363+ "world.geocache.cache.attribute#specialEquipment",
6464+ "world.geocache.cache.attribute#night",
6565+ "world.geocache.cache.attribute#garminChirp",
6666+ "world.geocache.cache.attribute#letterbox",
6767+ "world.geocache.cache.attribute#compass",
6868+ "world.geocache.cache.attribute#quick",
6969+ "world.geocache.cache.attribute#traveller",
7070+ "world.geocache.cache.attribute#byop",
7171+ "world.geocache.cache.attribute#magnetic",
7272+ "world.geocache.cache.attribute#audio",
7373+ "world.geocache.cache.attribute#offset",
7474+ "world.geocache.cache.attribute#usb",
7575+ "world.geocache.cache.attribute#surveyBenchmark",
7676+ "world.geocache.cache.attribute#woods",
7777+ "world.geocache.cache.attribute#historic",
7878+ "world.geocache.cache.attribute#advertisement",
7979+ "world.geocache.cache.attribute#limitedaccess",
8080+ "world.geocache.cache.attribute#guestBook",
8181+ "world.geocache.cache.attribute#challenge",
8282+ "world.geocache.cache.attribute#urban",
8383+ "world.geocache.cache.attribute#bikeFriendly",
8484+ "world.geocache.cache.attribute#keypair",
8585+ "world.geocache.cache.attribute#noInternet",
8686+ "world.geocache.cache.attribute#bushwhacking",
8787+ "world.geocache.cache.attribute#underwater",
8888+ "world.geocache.cache.attribute#cave",
8989+ ]
9090+ }
9191+ },
9292+ "description": {
9393+ "type": "string",
9494+ "maxLength": 10000,
9595+ "maxGraphemes": 1000,
9696+ "description": "A description for the geocache. "
9797+ },
9898+ "pubkey": {
9999+ /*
100100+ the idea here is basically a fancier method of doing password verification
101101+ for visits to a geocache:
102102+ - the creator generates an ed25519 keypair (chosen for its small key sizes)
103103+ - the pubkey gets logged with the record
104104+ - the privkey gets deployed with the geocache
105105+ - visitors to the cache save the privkey
106106+ - visitors can sign a message with the discovered private key
107107+ - this message gets logged with their visit record
108108+ - the appview can "verify" the cache using the pubkey to decrypt the message
911099292- some of these aren't useful to us (OCNA only, for example), but most are
9393- probably worth porting over 1:1. we also could add new ones.
9494- */
9595- "type": "array",
9696- "description": "Attributes which describe the geocache",
9797- "items": {
9898- "type": "union",
9999- // for now i'm not going to list every single one, but just the general idea
100100- // based off of attributes on opencaching
101101- "refs": [
102102- "world.geocache.attribute#snakes",
103103- "world.geocache.attribute#garminchirp",
104104- "world.geocache.attribute#woods",
105105- "world.geocache.attribute#byop",
106106- // ...
107107- ]
108108- }
109109- },
110110- "description": {
111111- "type": "string",
112112- "maxLength": 10000,
113113- "maxGraphemes": 1000,
114114- "description": "A description for the geocache. "
115115- },
116116- "pubkey": {
117117- /*
118118- the idea here is basically a fancier method of doing password verification
119119- for visits to a geocache:
120120- - the creator generates an ed25519 keypair (chosen for its small key sizes)
121121- - the pubkey gets logged with the record
122122- - the privkey gets deployed with the geocache
123123- - visitors to the cache save the privkey
124124- - visitors can sign a message with the discovered private key
125125- - this message gets logged with their visit record
126126- - the appview can "verify" the cache using the pubkey to decrypt the message
110110+ the exact protocol for this remains to be explored, but i think it's a fun idea.
127111128128- the exact protocol for this remains to be explored, but i think it's a fun idea.
129129-130130- there's also a riff on this idea that might work well with the "moving" cache type:
131131- - each geocacher has a keypair
132132- - the original owner plants the geocache, and signs off their visit with their key
133133- - the next finder takes the geocache home, and logs their ownership signing with their key, referring to the last owner
134134- - this then creates a cryptographically signed history of the cache's location history
112112+ there's also a riff on this idea that might work well with the "moving" cache type:
113113+ - each geocacher has a keypair
114114+ - the original owner plants the geocache, and signs off their visit with their key
115115+ - the next finder takes the geocache home, and logs their ownership signing with their key, referring to the last owner
116116+ - this then creates a cryptographically signed history of the cache's location history
135117136136- yes, that's basically a stupid blockchain. but it's kinda silly in the good way.
118118+ yes, that's basically a stupid blockchain. but it's kinda silly in the good way.
137119138138- i mean, every record on a user's PDS is able to be proven to originate from the owner,
139139- so maybe you could still share a single private key that moves with the geocache?
140140- much to be thought about...
141141- */
142142- "type": "bytes",
143143- "maxLength": 57,
144144- "createdAt": {
145145- "type": "string",
146146- "format": "datetime",
147147- "description": "When the geocache was first created"
120120+ i mean, every record on a user's PDS is able to be proven to originate from the owner,
121121+ so maybe you could still share a single private key that moves with the geocache?
122122+ much to be thought about...
123123+ */
124124+ "type": "bytes",
125125+ "maxLength": 57,
126126+ "createdAt": {
127127+ "type": "string",
128128+ "format": "datetime",
129129+ "description": "When the geocache was first created"
130130+ }
148131 }
149132 }
150133 }
134134+ },
135135+ "status": {
136136+ "type": "string",
137137+ "description": "The status of the geocache",
138138+ "default": "world.geocache.cache#staging",
139139+ "knownValues": [
140140+ "world.geocache.cache.status#active",
141141+ "world.geocache.cache.status#dead",
142142+ "world.geocache.cache.status#done",
143143+ "world.geocache.cache.status#moved",
144144+ "world.geocache.cache.status#unknown",
145145+ "world.geocache.cache.status#staging",
146146+ "world.geocache.cache.status#asleep",
147147+ ]
148148+ },
149149+ "active": {
150150+ "type": "token",
151151+ "description": "This geocache is accessible."
152152+ },
153153+ "dead": {
154154+ "type": "token",
155155+ "description": "This geocache is inaccessible, and not expected to become accessible again."
156156+ },
157157+ "done": {
158158+ "type": "token",
159159+ "description": "This geocache was a time limited experience, and is now over."
160160+ },
161161+ "moved": {
162162+ "type": "token",
163163+ "description": "This geocache has been moved."
164164+ },
165165+ "unknown": {
166166+ "type": "token",
167167+ "description": "This geocache's status is not known."
168168+ },
169169+ "staging": {
170170+ "type": "token",
171171+ "description": "This geocache has yet to be deployed."
172172+ },
173173+ "asleep": {
174174+ "type": "token",
175175+ "description": "This geocache is temporarily inaccessible, but will become accessible again at some known time."
176176+ },
177177+ "cacheType": {
178178+ "type": "string",
179179+ "default": "world.geocache.cache#traditional",
180180+ /*
181181+ there's a few cache types that opencaching has which i'm not sure about
182182+ - moving
183183+ this is the most interesting one -- this represents a geocache that is moving
184184+ between each find (typically the finder moves the cache, updates the coordinates
185185+ after finding it). atproto does not currently have shared records, so you can't
186186+ do it that way.
187187+188188+ my immediate thought would be: a special subset of the geocache lexicon which
189189+ has a parameter for "nextLocation" -- the finder of the cache logs their visit,
190190+ not as a traditional "visit" lexicon, but instead as a "movedCache". while this would
191191+ introduce friction in that you would need the owner to update the cache, it would
192192+ be a pretty simple implementation from then on. the appview would just need to
193193+ keep track of successive moves and display them to the user. you'd also get a mostly free
194194+ history view, which could be super fun!
195195+196196+ if combined with the idea of pubkey verification, you could even automate the transfer
197197+ of a geocache -- the appview listens for a visit that has a linkback, verifies that
198198+ the signature is properly decrypted, and then would update the record on the original
199199+ owner's PDS to point to the first finder...
200200+ - event
201201+ the way this is described on opencaching seems to just represent like,
202202+ an in person meetup or something like that. not sure we need this one.
203203+ it would provide some feature pairity to opencaching, at least?
204204+ - webcam
205205+ these represent geocaches which use a webcam to log visits.
206206+ i don't see why this can't just be an attribute of a cache.
207207+ */
208208+ "knownValues": [
209209+ "world.geocache.cache#traditional",
210210+ "world.geocache.cache#multi",
211211+ "world.geocache.cache#moving",
212212+ "world.geocache.cache#puzzle",
213213+ "world.geocache.cache#digital",
214214+ "world.geocache.cache#virtual",
215215+ "world.geocache.cache#roaming",
216216+ "world.geogache.cache#other"
217217+ ]
218218+ },
219219+ "traditional": {
220220+ "type": "token",
221221+ "description": "This is a traditional geocache, containing at minimum a container and a logbook."
222222+ },
223223+ "multi": {
224224+ "type": "token",
225225+ "description": "This geocache involves at least two locations, usually found by hints left in the first geocache."
226226+ },
227227+ "moving": {
228228+ "type": "token",
229229+ "description": "This geocache changes its location after each find."
230230+ },
231231+ "puzzle": {
232232+ "type": "token",
233233+ "description": "This geocache involves a puzzle to determine the location of the actual cache. Location data refers to a related reference point."
234234+ },
235235+ "digital": {
236236+ "type": "token",
237237+ "description": "This geocache exists in cyberspace."
238238+ },
239239+ "virtual": {
240240+ "type": "token",
241241+ "description": "This geocache exists in the form of a location only."
242242+ },
243243+ "roaming": {
244244+ "type": "token",
245245+ "description": "This geocache roams around the world, typically with the owner of the cache."
246246+ },
247247+ "other": {
248248+ "type": "token",
249249+ "description": "This geocache is not well defined by any current type token."
151250 },
152251 }
153252}