# I am the Watcher. I am your guide through this vast new twtiverse.
# 
# Usage:
#     https://watcher.sour.is/api/plain/users              View list of users and latest twt date.
#     https://watcher.sour.is/api/plain/twt                View all twts.
#     https://watcher.sour.is/api/plain/mentions?uri=:uri  View all mentions for uri.
#     https://watcher.sour.is/api/plain/conv/:hash         View all twts for a conversation subject.
# 
# Options:
#     uri     Filter to show a specific users twts.
#     offset  Start index for quey.
#     limit   Count of items to return (going back in time).
# 
# twt range = 1 196314
# self = https://watcher.sour.is?offset=170199
# next = https://watcher.sour.is?offset=170299
# prev = https://watcher.sour.is?offset=170099
@aelaraji Yeah, that’s pretty close to what was outlined here: https://twtxt.net/twt/ansuy4a 😅
[47°09′22″S, 126°43′49″W] Wind speed: 95kph -- batteries low
@prologic Unfortunately it only work if I pull the feed in debug mode jenny -D otherwise, it misses things up if I add that snippet of text to links in my .config/jenny/follow file 😅 Anyway, it was a nice try.
@prologic Unfortunately it only work if I pull the feed in debug mode jenny -D otherwise, it misses things up if I add that snippet of text to links in my .config/jenny/follow file 😅 Anyway, it was a nice try.
@prologic Unfortunately it only work if I pull the feed in debug mode jenny -D otherwise, it misses things up if I add that snippet of text to links in my .config/jenny/follow file 😅 Anyway, it was a nice try.
So this is a great thread. I have been thinking about this too.. and what if we are coming at it from the wrong direction? Identity being tied to a given URL has always been a pain point. If i get a new URL its almost as if i have a new identity because not only am I serving at a new location but all my previous communications are broken because the hashes are all wrong.

What if instead we used this idea of signatures to thread the URLs together into one identity? We keep the URL to Hash in place. Changing that now is basically a no go. But we can create a signature chain that can link identities together. So if i move to a new URL i update the chain hosted by my primary identity to include the new URL. If i have an archived feed that the old URL is now dead, we can point to where it is now hosted and use the current convention of hashing based on the first url:

The signature chain can also be used to rotate to new keys over time. Just sign in a new key or revoke an old one. The prior signatures remain valid within the scope of time the signatures were made and the keys were active.

The signature file can be hosted anywhere as long as it can be fetched by a reasonable protocol. So say we could use a webfinger that directs to the signature file? you have an identity like frank@beans.co that will discover a feed at some URL and a signature chain at another URL. Maybe even include the most recent signing key?

From there the client can auto discover old feeds to link them together into one complete timeline. And the signatures can validate that its all correct.

I like the idea of maybe putting the chain in the feed preamble and keeping the single self contained file.. but wonder if that would cause lots of clutter? The signature chain would be something like a log with what is changing (new key, revoke, add url) and a signature of the change + the previous signature.


# chain: ADDKEY kex14zwrx68cfkg28kjdstvcw4pslazwtgyeueqlg6z7y3f85h29crjsgfmu0w 
# sig: BEGIN SALTPACK SIGNED MESSAGE. ... 
# chain: ADDURL https://txt.sour.is/user/xuu
# sig: BEGIN SALTPACK SIGNED MESSAGE. ...
# chain: REVKEY kex14zwrx68cfkg28kjdstvcw4pslazwtgyeueqlg6z7y3f85h29crjsgfmu0w
# sig: ...
So this is a great thread. I have been thinking about this too.. and what if we are coming at it from the wrong direction? Identity being tied to a given URL has always been a pain point. If i get a new URL its almost as if i have a new identity because not only am I serving at a new location but all my previous communications are broken because the hashes are all wrong.

What if instead we used this idea of signatures to thread the URLs together into one identity? We keep the URL to Hash in place. Changing that now is basically a no go. But we can create a signature chain that can link identities together. So if i move to a new URL i update the chain hosted by my primary identity to include the new URL. If i have an archived feed that the old URL is now dead, we can point to where it is now hosted and use the current convention of hashing based on the first url:

The signature chain can also be used to rotate to new keys over time. Just sign in a new key or revoke an old one. The prior signatures remain valid within the scope of time the signatures were made and the keys were active.

The signature file can be hosted anywhere as long as it can be fetched by a reasonable protocol. So say we could use a webfinger that directs to the signature file? you have an identity like frank@beans.co that will discover a feed at some URL and a signature chain at another URL. Maybe even include the most recent signing key?

From there the client can auto discover old feeds to link them together into one complete timeline. And the signatures can validate that its all correct.

I like the idea of maybe putting the chain in the feed preamble and keeping the single self contained file.. but wonder if that would cause lots of clutter? The signature chain would be something like a log with what is changing (new key, revoke, add url) and a signature of the change + the previous signature.


# chain: ADDKEY kex14zwrx68cfkg28kjdstvcw4pslazwtgyeueqlg6z7y3f85h29crjsgfmu0w 
# sig: BEGIN SALTPACK SIGNED MESSAGE. ... 
# chain: ADDURL https://txt.sour.is/user/xuu
# sig: BEGIN SALTPACK SIGNED MESSAGE. ...
# chain: REVKEY kex14zwrx68cfkg28kjdstvcw4pslazwtgyeueqlg6z7y3f85h29crjsgfmu0w
# sig: ...
[47°09′20″S, 126°43′43″W] Working impossible due to blizzard
****
A morir al palo. ⌘ Read more****
IMO we just have to fix the identity problem and figure out how to detect or support edits.
IMO we just have to fix the identity problem and figure out how to detect or support edits.
@sorenpeter No, this is what I want to avoid. For many reasons I stated before, content addressing or hashing is far better here for threading in a decentralized way.
@sorenpeter No, this is what I want to avoid. For many reasons I stated before, content addressing or hashing is far better here for threading in a decentralized way.
@prologic do that mean that for every new post (not replies) the client will have to generate a UUID or similar when posting and add that to to the twt?
@prologic do that mean that every new post (not replies) will have to generate their own UUID or similar when posting?
@prologic do that mean that for every new post (not replies) the client will have to generate a UUID or similar when posting and add that to to the twt?
@prologic do that mean that for every new post (not replies) the client will have to generate a UUID or similar when posting and add that to to the twt?
@prologic do that mean that for every new post (not replies) the client will have to generate a UUID or similar when posting and add that to to the twt?
[47°09′55″S, 126°43′36″W] Working impossible due to thunderstorm
- ¡Había una ratita rosa! Te he salvado la vida. ¡Dame comida!-
/https://duque-terron.cat/media/photos/IMG_1837.jpeg) #catsoftwtxt
- ¡Había una ratita rosa! Te he salvado la vida. ¡Dame comida!-
#catsoftwtxt
- ¡Había una ratita rosa! Te he salvado la vida. ¡Dame comida!-
#catsoftwtxt
[47°09′41″S, 126°43′31″W] Automatic systems disengaged due to heavy rain
Merci, @movq! I will keep you posted. :-)
@movq Same here for sure. :-D Great, I just saw the start was postponed by yet another half hour. I could have slept longer. Well, gonna catch the later train then.
@prologic yup.
@lyse I personally think that we just go with a magic timestamp approach. It's simpler and easier to implement across the major clients that are still actively developed.

The question is how much time do we give ourselves as we're all a bit time poor and I can't imagine we would do this quickly.
@lyse I personally think that we just go with a magic timestamp approach. It's simpler and easier to implement across the major clients that are still actively developed.

The question is how much time do we give ourselves as we're all a bit time poor and I can't imagine we would do this quickly.
@movq if you do win the lottery, don't forget to include us so we can all join in and share the things that we like to tinker with instead of this whole rat race. 🤣
@movq if you do win the lottery, don't forget to include us so we can all join in and share the things that we like to tinker with instead of this whole rat race. 🤣
@bender Big photo capability upgrade?
@bender Big photo capability upgrade?
@aelaraji Nice hack! 👌
@aelaraji Nice hack! 👌
I wonder if bento has slightly missed the key to being a total genius approach to host management. ok hear me out. each node periodically pulls configuration from a coordination node that hosts a binary cache. the admin may make changes and pre-build them maybe kick off an update task manually if they want, but the point is there's an automated checkin. for my case, the device I have available for coordination isn't really capable of hosting a binary cache for any of my other machines. the nix store for my dev machine is larger than the entire disk of the coordinator! and due to the yearly heat my best machine can't be reliably powered on all the time. so i started thinking to myself, "self, what if instead of having a central coordinator we fetched configuration from a reliable git mirror (maybe git+torrent some day) and consume it as a flake. the source could even be swapped out using a flake registry (so you don't even have to commit to self-hosting anything other than a json file). then managed hosts only have to be setup to consume the registry and the shared flake (which registers the update agent) and DONE?"
🧮 USERS:1 FEEDS:2 TWTS:1088 ARCHIVED:78704 CACHE:2506 FOLLOWERS:17 FOLLOWING:14
@movq @prologic Hey! I may have found a silly trick to announce my following to people hosting their feeds on the Gemini space using the requested URI itself instead of relaying on the USER Agent 😂. I've copied my current feed over to my (to be) Gemlog for testing. And if I do a jenny -D "gemini://gem.aelaraji.com/twtxt.txt?follower=aelaraji@https://aelaraji.com/twtxt.txt" and this happens:

A) As a follower, I get the feed as usual.
B) As the feed owner, I get this in logs:

> hostname:1965 - "gemini://gem.aelaraji.com/twtxt.txt?follower=aelaraji@https://aelaraji.com/twtxt.txt" 20 "text/plain;lang=en-US"

You could do the same for Gopher feeds but only if you want to announce yourself by throwing in an error in their logs, then you'll need a second request to fetch the feed. jenny -D "gopher://gopher.aelaraji.com/twtxt.txt&follower=aelaraji@https:/aelaraji.com/twtxt.txt" gave me this :

> gopher.aelaraji.com:70 - [09/Sep/2024:22:08:54 +0000] "GET 0/twtxt.txt&follower=aelaraji@https:/aelaraji.com/twtxt.txt HTTP/1.0" 404 0 "" "Unknown gopher client"

NB: the follower=... string won't appear in gopher logs after a ? but if I replace it with a + or a & and it works. There will be a missing / after the https:. Probably a client thing.
@movq @prologic Hey! I may have found a silly trick to announce my following to people hosting their feeds on the Gemini space using the requested URI itself instead of relaying on the USER Agent 😂. I've copied my current feed over to my (to be) Gemlog for testing. And if I do a jenny -D "gemini://gem.aelaraji.com/twtxt.txt?follower=aelaraji@https://aelaraji.com/twtxt.txt" and this happens:

A) As a follower, I get the feed as usual.
B) As the feed owner, I get this in logs:

> hostname:1965 - "gemini://gem.aelaraji.com/twtxt.txt?follower=aelaraji@https://aelaraji.com/twtxt.txt" 20 "text/plain;lang=en-US"

You could do the same for Gopher feeds but only if you want to announce yourself by throwing in an error in their logs, then you'll need a second request to fetch the feed. jenny -D "gopher://gopher.aelaraji.com/twtxt.txt&follower=aelaraji@https:/aelaraji.com/twtxt.txt" gave me this :

> gopher.aelaraji.com:70 - [09/Sep/2024:22:08:54 +0000] "GET 0/twtxt.txt&follower=aelaraji@https:/aelaraji.com/twtxt.txt HTTP/1.0" 404 0 "" "Unknown gopher client"

NB: the follower=... string won't appear in gopher logs after a ? but if I replace it with a + or a & and it works. There will be a missing / after the https:. Probably a client thing.
@movq @prologic Hey! I may have found a silly trick to announce my following to people hosting their feeds on the Gemini space using the requested URI itself instead of relaying on the USER Agent 😂. I've copied my current feed over to my (to be) Gemlog for testing. And if I do a jenny -D "gemini://gem.aelaraji.com/twtxt.txt?follower=aelaraji@https://aelaraji.com/twtxt.txt" and this happens:

A) As a follower, I get the feed as usual.
B) As the feed owner, I get this in logs:

> hostname:1965 - "gemini://gem.aelaraji.com/twtxt.txt?follower=aelaraji@https://aelaraji.com/twtxt.txt" 20 "text/plain;lang=en-US"

You could do the same for Gopher feeds but only if you want to announce yourself by throwing in an error in their logs, then you'll need a second request to fetch the feed. jenny -D "gopher://gopher.aelaraji.com/twtxt.txt&follower=aelaraji@https:/aelaraji.com/twtxt.txt" gave me this :

> gopher.aelaraji.com:70 - \n "GET 0/twtxt.txt&follower=aelaraji@https:/aelaraji.com/twtxt.txt HTTP/1.0" 404 0 "" "Unknown gopher client"

NB: the follower=... string won't appear in gopher logs after a ? but if I replace it with a + or a & and it works. There will be a missing / after the https:. Probably a client thing.
if you want your computer to be able to sleep, you'll need a measuring tape and a scientific calculator. first, measure each byte that you have in RAM and take the square root. add that to your total length. we'll need that number later on.
@prologic iPhone 16 Pro Max for you, for sure. If significant other likes to take pictures as much as mine, then one for her too. That's $1,200 each (with 256GB storage).
[47°09′10″S, 126°43′06″W] Automatic systems disengaged due to blizzard
I went straight to bed after posting this and slept for 3 hours. 😩 Can’t I just win the lottery and be done with this whole “money” thing? 🤪

@lyse Oof, well, good luck. Those multi-day meetings are usually really exhausting (and mostly pointless) in our company, hopefully it’s different at yours. ✌️
I went straight to bed after posting this and slept for 3 hours. 😩 Can’t I just win the lottery and be done with this whole “money” thing? 🤪

@lyse Oof, well, good luck. Those multi-day meetings are usually really exhausting (and mostly pointless) in our company, hopefully it’s different at yours. ✌️
I went straight to bed after posting this and slept for 3 hours. 😩 Can’t I just win the lottery and be done with this whole “money” thing? 🤪

@lyse Oof, well, good luck. Those multi-day meetings are usually really exhausting (and mostly pointless) in our company, hopefully it’s different at yours. ✌️
I went straight to bed after posting this and slept for 3 hours. 😩 Can’t I just win the lottery and be done with this whole “money” thing? 🤪

@lyse Oof, well, good luck. Those multi-day meetings are usually really exhausting (and mostly pointless) in our company, hopefully it’s different at yours. ✌️
@lyse Indeed, great news! If you need testers at some point, let me know. 😅
@lyse Indeed, great news! If you need testers at some point, let me know. 😅
@lyse Indeed, great news! If you need testers at some point, let me know. 😅
@lyse Indeed, great news! If you need testers at some point, let me know. 😅
Lest we forget … https://www.youtube.com/watch?v=mp5gksq_OEI … !
Lest we forget … https://www.youtube.com/watch?v=mp5gksq_OEI … !
Lest we forget … https://www.youtube.com/watch?v=mp5gksq_OEI … !
Lest we forget … https://www.youtube.com/watch?v=mp5gksq_OEI … !
@falsifian Regarding your last paragraph: Back in December 2020, we already once changed the hashing. I think that was my first contribution, breaking everything by switching to RFC 3339 for the timestamp format. ;-) I'm computing two hashes in my client, the old and current one. And then I just select whatever matching parent exists to build the thread tree.

I could do that again in my client, but you're right, it's a different story for jenny. If I'm not mistaken, In-Reply-To could contain several hashes, but the Message-ID header is the issue.

By increasing the hash length for a potential future change, clients could tell, which algorithm to use.

Maybe we could define a magic timestamp in the future that marks the cutoff point. Use the current implementation for messages authored before that magic date or the new algorithm for all messages after that.

But eventually, all clients have to be updated. There's no way around that, I believe. Simplicity is key and my magic time already adds complexity. :-/
@movq @aelaraji @bender Why not have both Jupiter and Venus together? https://www.youtube.com/watch?v=oXyCORLeLd0 I don't understand anything either, but it just sounds great to my ears.

> if not I am editing and breaking replies!

Bwahahahaaa! :'-D
@bender I doubt I'll be able to watch it live 🤣 But by all means, please Yarns all the goodies 😅
@bender I doubt I'll be able to watch it live 🤣 But by all means, please Yarns all the goodies 😅
Nice, thanks for the offer, @bender! You have to be a bit patient, though, it'll take a while until there is something to actually worth messing with. :-)
Getting ready for the Apple Event. Are you watching it live, @prologic, or afterwards? :-P
@movq @prologic :-D

It's like that for months. :-( And tomorrow I even gotta go into the office for some two day meeting, but I only attend a single day. On the positive side, I'm gonna see some workmates that I haven't ever met in the real world or for a very long time.
@bender Kind of mirrored the ssh and ssh-keygen utilities. No reason really.
@bender Kind of mirrored the ssh and ssh-keygen utilities. No reason really.
@bender


$ echo 'hello world' | ./salty -i ./test_ed25519 --ssh-key --sign
@bender


$ echo 'hello world' | ./salty -i ./test_ed25519 --ssh-key --sign
@prologic any reason why there is salty, and salty-keygen? Why not both into one?
@prologic hey, what's the one liner to sign using an SSH key with salty?
@bender Ahh yeah sorry about that 🤣 You were getting confused between salty.im and salty. The later of which salty.im _actually_ uses and formed the basis of everything else. It's a simple robust library and command-line tools with good test coverage. The lowest building block 😅
@bender Ahh yeah sorry about that 🤣 You were getting confused between salty.im and salty. The later of which salty.im _actually_ uses and formed the basis of everything else. It's a simple robust library and command-line tools with good test coverage. The lowest building block 😅
I think I know what I did wrong. LOL. I used the wrong repository. Going for go install go.mills.io/salty/cmd/salty@latest instead. Duh!
@prologic So, I did go install go.salty.im/saltyim/cmd/salty-chat@latest, moved salty-chat to my bin as salty, and that one liner isn't working. What am I doing wrong?
[47°09′53″S, 126°43′56″W] Automatic systems disengaged due to thunderstorm
@prologic excellent, thanks!
@prologic excellent, thanks!
Pinellas County - Cool down: 0.83 miles, 00:09:44 average pace, 00:08:06 duration

#running
Pinellas County - Cool down: 0.83 miles, 00:09:44 average pace, 00:08:06 duration

#running
Pinellas County - Cool down: 0.83 miles, 00:09:44 average pace, 00:08:06 duration

#running
@movq That bad eh? 😅
@movq That bad eh? 😅
It’s one of those days.

It’s one of those days.

It’s one of those days.

It’s one of those days.

Pinellas County - Base: 4.15 miles, 00:08:59 average pace, 00:37:18 duration
Good workout keeping it aerobic for the most part.
#running
Pinellas County - Base: 4.15 miles, 00:08:59 average pace, 00:37:18 duration
Good workout keeping it aerobic for the most part.
#running
Pinellas County - Base: 4.15 miles, 00:08:59 average pace, 00:37:18 duration
Good workout keeping it aerobic for the most part.
#running
For example:


$ echo 'hello world' | ./salty -i ./test.key -s | ./salty -i ./test.key -v
# signed by: kex1yfzzthmsdlqhgwzafy9zpjze6a0asxf6y552dp4yhvq66a4jje0qxqapvd
hello world
For example:


$ echo 'hello world' | ./salty -i ./test.key -s | ./salty -i ./test.key -v
# signed by: kex1yfzzthmsdlqhgwzafy9zpjze6a0asxf6y552dp4yhvq66a4jje0qxqapvd
hello world
@bender Yes of course it can 😅 Sorry I missed your question on IRC 😢
@bender Yes of course it can 😅 Sorry I missed your question on IRC 😢
@prologic can salty verify ed25519 signed messages? I asked on IRC, but never got a reply (or I missed it).
@jmjl howdy! Sorry for mistaken you with https://blog.nfld.uk/ (jlj), but glad to connect. Cheers!
@jmjl howdy! Sorry for mistaken you with https://blog.nfld.uk/ (jlj), but glad to connect. Cheers!
@mckinley To answer some of your questions:

> Are SSH signatures standardized and are there robust software libraries that can handle them? We’ll need a library in at least Python and Go to provide verified feed support with the currently used clients.

We already have this. Ed25519 libraries exist for all major languages. Aside from using ssh-keygen -Y sign and ssh-keygen -Y verify, you can also use the salty CLI itself (https://git.mills.io/prologic/salty), and I'm sure there are other command-line tools that _could_ be used too.

> If we all implemented this, every twt hash would suddenly change and every conversation thread we’ve ever had would at least lose its opening post.

Yes. This would happen, so we'd have to make a decision around this, either a) a cut-off point or b) some way to progressively transition.
@mckinley To answer some of your questions:

> Are SSH signatures standardized and are there robust software libraries that can handle them? We’ll need a library in at least Python and Go to provide verified feed support with the currently used clients.

We already have this. Ed25519 libraries exist for all major languages. Aside from using ssh-keygen -Y sign and ssh-keygen -Y verify, you can also use the salty CLI itself (https://git.mills.io/prologic/salty), and I'm sure there are other command-line tools that _could_ be used too.

> If we all implemented this, every twt hash would suddenly change and every conversation thread we’ve ever had would at least lose its opening post.

Yes. This would happen, so we'd have to make a decision around this, either a) a cut-off point or b) some way to progressively transition.
@bender Holy shit that pod is still alive?! 🤔
@bender Holy shit that pod is still alive?! 🤔
@sorenpeter WebFinger requires additional setup that whilsts helps to solve the "identity" problem in an "abstract" way, that extra infra that needs to be setup a) isn't trivial and b) hard to support on "shared hosting".

Sharing hosting is also the reason why you can't just use part of a URL really.
@sorenpeter WebFinger requires additional setup that whilsts helps to solve the "identity" problem in an "abstract" way, that extra infra that needs to be setup a) isn't trivial and b) hard to support on "shared hosting".

Sharing hosting is also the reason why you can't just use part of a URL really.
On my blog: Developer Diary, Chrysanthemum Day https://john.colagioia.net/blog/2024/09/09/chrysanthemum.html #programming #project #devjournal