In-reply-to » I'm finally continuing with my tt rewrite in Go. So, I thought I use the shiny io/fs.FS. That's supposed to be a super cool new file system API. It allowed me to write tests more elegantly. I don't have to place actual test files on disk, but can keep everything nicely in RAM with testing/fstest.MapFS. That actually worked out great, I do like that.

@lyse@lyse.isobeef.org Indeed, great news! If you need testers at some point, let me know. 😅

⤋ Read More
In-reply-to » @lyse This looks like a nice way to do it.

@falsifian@www.falsifian.org 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. :-/

⤋ Read More
In-reply-to » @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@twtxt.net Kind of mirrored the ssh and ssh-keygen utilities. No reason really.

⤋ Read More
In-reply-to » @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 😅

@prologic@twtxt.net any reason why there is salty, and salty-keygen? Why not both into one?

⤋ Read More
In-reply-to » For example:

@bender@twtxt.net 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 😅

⤋ Read More
In-reply-to » On the Subject of Feed Identities; I propose the following:

@mckinley@twtxt.net 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.

⤋ Read More
In-reply-to » @falsifian In my opinion it was a mistake that we defined the first url field in the feed to define the URL for hashing. It should have been the last encountered one. Then, assuming append-style feeds, you could override the old URL with a new one from a certain point on:

@sorenpeter@darch.dk 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.

⤋ Read More
In-reply-to » @falsifian In my opinion it was a mistake that we defined the first url field in the feed to define the URL for hashing. It should have been the last encountered one. Then, assuming append-style feeds, you could override the old URL with a new one from a certain point on:

how little data is needed for generating the hashes? Instead of the full URL, can we makedo with just the domain (example.net) so we avoid the conflicts with gemini://, https:// and only http:// (like in my own twtxt.txt) or construct something like like a webfinger id nick@domain (also used by mastodon etc.) from the domain and nick if there, else use domain as nick as well

⤋ Read More
In-reply-to » @prologic No, it’s all just speculation and I don’t like spreading rumors. 😅 It would be more interesting to hear from the twtxt folks themselves why they stopped working on the original twtxt.

But in all seriousness I’ve only ever wanted to improve Twtxt without sacrificing its simplicity too much.

⤋ Read More
In-reply-to » @prologic Some criticisms and a possible alternative direction:

@falsifian@www.falsifian.org

Key rotation

Key rotation is useful for security reasons, but I don’t think it’s necessary here because it’s only used for verifying one’s identity. It’s no different (to me) than Nostr or a cryptocurrency. You change your key, you change your identity.

It makes maintaining a feed more complicated.

This is an additional step that you’d have to perform, but I definitely wouldn’t want to require it for compatibility reasons. I don’t see it as any more complicated than computing twt hashes for each post, which already requires you to have a non-trivial client application.

Instead, maybe…allow old urls to be rotated out?

That could absolutely work and might be a better solution than signatures.

HTTPS is supposed to do [verification] anyway.

TLS provides verification that nobody is tampering with or snooping on your connection to a server. It doesn’t, for example, verify that a file downloaded from server A is from the same entity as the one from server B.

feed locations [being] URLs gives some flexibility

It does give flexibility, but perhaps we should have made them URIs instead for even more flexibility. Then, you could use a tag URI, urn:uuid:*, or a regular old URL if you wanted to. The spec seems to indicate that the url tag should be a working URL that clients can use to find a copy of the feed, optionally at multiple locations. I’m not very familiar with IP{F,N}S but if it ensures you own an identifier forever and that identifier points to a current copy of your feed, it could be a great way to fix it on an individual basis without breaking any specs :)

⤋ Read More
In-reply-to » On the Subject of Feed Identities; I propose the following:

My first thought when reading this was to go to my typical response and suggest we use Nostr instead of introducing cryptography to Twtxt. The more I thought about it, however, the more it made sense.

  1. It solves the problem elegantly, because the feed can move anywhere and the twt hashes will remain the same.
  2. It provides proof that a post is made by the same entity as another post.
  3. It doesn’t break existing clients.
  4. Everyone already has SSH on their machine, so anyone creating feeds manually could adopt this easily.

There are a couple of elephants in the room that we ought to talk about.

  1. 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.
  2. 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.

⤋ Read More
In-reply-to » @prologic Some criticisms and a possible alternative direction:

@lyse@lyse.isobeef.org This looks like a nice way to do it.

Another thought: if clients can’t agree on the url (for example, if we switch to this new way, but some old clients still do it the old way), that could be mitigated by computing many hashes for each twt: one for every url in the feed. So, if a feed has three URLs, every twt is associated with three hashes when it comes time to put threads together.

A client stills need to choose one url to use for the hash when composing a reply, but this might add some breathing room if there’s a period when clients are doing different things.

(From what I understand of jenny, this would be difficult to implement there since each pseudo-email can only have one msgid to match to the in-reply-to headers. I don’t know about other clients.)

⤋ Read More
In-reply-to » I'm finally continuing with my tt rewrite in Go. So, I thought I use the shiny io/fs.FS. That's supposed to be a super cool new file system API. It allowed me to write tests more elegantly. I don't have to place actual test files on disk, but can keep everything nicely in RAM with testing/fstest.MapFS. That actually worked out great, I do like that.

@lyse@lyse.isobeef.org I just wanted to state that this is excellent news! Are you going to use some BubbleTea? 🙈

⤋ Read More
In-reply-to » I'm finally continuing with my tt rewrite in Go. So, I thought I use the shiny io/fs.FS. That's supposed to be a super cool new file system API. It allowed me to write tests more elegantly. I don't have to place actual test files on disk, but can keep everything nicely in RAM with testing/fstest.MapFS. That actually worked out great, I do like that.

https://github.com/spf13/afero looks better, but has a gazillion dependencies. So that’s out.

⤋ Read More

I’m finally continuing with my tt rewrite in Go. So, I thought I use the shiny io/fs.FS. That’s supposed to be a super cool new file system API. It allowed me to write tests more elegantly. I don’t have to place actual test files on disk, but can keep everything nicely in RAM with testing/fstest.MapFS. That actually worked out great, I do like that.

However, os.DirFS("/") for production code is just a terrible solution. I noted that OS paths and io/fs.FS paths are fundamentally different. This new API does not allow leading slashes in the passed paths. This results in an error. So, I have to cut the leading slash off myself.

Also, the whole thing is totally useless on Windows, because of the drives. Simply does not work at all. Well, honestly, I don’t care the slightest bit about that operating system, but it would be nice if this concept were cross-platform.

I haven’t tested it, but I’m pretty sure relative paths or ~ do also not work. I have to first build absolute paths myself. Unfortunately, there is no builtin helper to translate an OS path into a io/fs.FS path.

Of course, others noted these shortcomings and surprising results, too: https://github.com/golang/go/issues/44279 There is no OSFileSystem implementation that would simply allow the easy transition from all the classical os.* functionality to io/fs.FS. And they also do not wanna add something like that either. Sigh.

I’m really wondering what they were thinking when introducing this. :-?

Even though, it’s very silly, I’m gonna keep using it. At least for now. Tests have been written. I’m not keen on rewriting them. Sigh.

⤋ Read More
In-reply-to » @falsifian In my opinion it was a mistake that we defined the first url field in the feed to define the URL for hashing. It should have been the last encountered one. Then, assuming append-style feeds, you could override the old URL with a new one from a certain point on:

For the record, out of the 89 feeds that I follow, only a single one has more than one # url = field:

gemini://gemini.ctrl-c.club/~nristen/twtxt.txt

And I wonder if @nristen@gemini.ctrl-c.club is aware that the order of those fields matter. 🤔

⤋ Read More