O mistério de M000015 JOAO A. FERNANDES 150000190 numa espreitadela à história da computação em Portugal nos anos 70:
https://blog.jgc.org/2024/10/rabbit-hole-stumbling-across-two.html?m=1
I share I did write up an algorithm for it at some point I think it is lost in a git comment someplace. I’ll put together a pseudo/go code this week.
Super simple:
Making a reply:
- If yarn has one use that. (Maybe do collision check?)
- Make hash of twt raw no truncation.
- Check local cache for shortest without collision
- in SQL:
select len(subject) where head_full_hash like subject || '%'
- in SQL:
Threading:
- Get full hash of head twt
- Search for twts
- in SQL:
head_full_hash like subject || '%' and created_on > head_timestamp
- in SQL:
The assumption being replies will be for the most recent head. If replying to an older one it will use a longer hash.
@prologic@twtxt.net Regarding the new way of generating twt-hashes, to me it makes more sense to use tabs as separator instead of spaces, since the you can just copy/past a line directly from a twtxt-file that already go a tab between timestamp and message. But tabs might be hard to “type” when you are in a terminal, since it will activate autocomplete…🤔
Another thing, it seems that you sugget we only use the domain in the hash-creation and not the full path to the twtxt.txt
$ echo -e "https://example.com 2024-09-29T13:30:00Z Hello World!" | sha256sum - | awk '{ print $1 }' | base64 | head -c 12
More thoughts about changes to twtxt (as if we haven’t had enough thoughts):
- There are lots of great ideas here! Is there a benefit to putting them all into one document? Seems to me this could more easily be a bunch of separate efforts that can progress at their own pace:
1a. Better and longer hashes.
1b. New possibly-controversial ideas like edit: and delete: and location-based references as an alternative to hashes.
1c. Best practices, e.g. Content-Type: text/plain; charset=utf-8
1d. Stuff already described at dev.twtxt.net that doesn’t need any changes.
We won’t know what will and won’t work until we try them. So I’m inclined to think of this as a bunch of draft ideas. Maybe later when we’ve seen it play out it could make sense to define a group of recommended twtxt extensions and give them a name.
Another reason for 1 (above) is: I like the current situation where all you need to get started is these two short and simple documents:
https://twtxt.readthedocs.io/en/latest/user/twtxtfile.html
https://twtxt.readthedocs.io/en/latest/user/discoverability.html
and everything else is an extension for anyone interested. (Deprecating non-UTC times seems reasonable to me, though.) Having a big long “twtxt v2” document seems less inviting to people looking for something simple. (@prologic@twtxt.net you mentioned an anonymous comment “you’ve ruined twtxt” and while I don’t completely agree with that commenter’s sentiment, I would feel like twtxt had lost something if it moved away from having a super-simple core.)All that being said, these are just my opinions, and I’m not doing the work of writing software or drafting proposals. Maybe I will at some point, but until then, if you’re actually implementing things, you’re in charge of what you decide to make, and I’m grateful for the work.
Some more arguments for a local-based treading model over a content-based one:
The format:
(#<DATE URL>)
or(@<DATE URL>)
both makes sense: # as prefix is for a hashtag like we allredy got with the(#twthash)
and @ as prefix denotes that this is mention of a specific post in a feed, and not just the feed in general. Using either can make implementation easier, since most clients already got this kind of filtering.Having something like
(#<DATE URL>)
will also make mentions via webmetions for twtxt easier to implement, since there is no need for looking up the#twthash
. This will also make it possible to make 3th part twt-mentions services.Supporting twt/webmentions will also increase discoverability as a way to know about both replies and feed mentions from feeds that you don’t follow.
@prologic@twtxt.net Thanks for writing that up!
I hope it can remain a living document (or sequence of draft revisions) for a good long time while we figure out how this stuff works in practice.
I am not sure how I feel about all this being done at once, vs. letting conventions arise.
For example, even today I could reply to twt abc1234 with “(#abc1234) Edit: …” and I think all you humans would understand it as an edit to (#abc1234). Maybe eventually it would become a common enough convention that clients would start to support it explicitly.
Similarly we could just start using 11-digit hashes. We should iron out whether it’s sha256 or whatever but there’s no need get all the other stuff right at the same time.
I have similar thoughts about how some users could try out location-based replies in a backward-compatible way (append the replyto: stuff after the legacy (#hash) style).
However I recognize that I’m not the one implementing this stuff, and it’s less work to just have everything determined up front.
Misc comments (I haven’t read the whole thing):
Did you mean to make hashes hexadecimal? You lose 11 bits that way compared to base32. I’d suggest gaining 11 bits with base64 instead.
“Clients MUST preserve the original hash” — do you mean they MUST preserve the original twt?
Thanks for phrasing the bit about deletions so neutrally.
I don’t like the MUST in “Clients MUST follow the chain of reply-to references…”. If someone writes a client as a 40-line shell script that requires the user to piece together the threading themselves, IMO we shouldn’t declare the client non-conforming just because they didn’t get to all the bells and whistles.
Similarly I don’t like the MUST for user agents. For one thing, you might want to fetch a feed without revealing your identty. Also, it raises the bar for a minimal implementation (I’m again thinking again of the 40-line shell script).
For “who follows” lists: why must the long, random tokens be only valid for a limited time? Do you have a scenario in mind where they could leak?
Why can’t feeds be served over HTTP/1.0? Again, thinking about simple software. I recently tried implementing HTTP/1.1 and it wasn’t too bad, but 1.0 would have been slightly simpler.
Why get into the nitty-gritty about caching headers? This seems like generic advice for HTTP servers and clients.
I’m a little sad about other protocols being not recommended.
I don’t know how I feel about including markdown. I don’t mind too much that yarn users emit twts full of markdown, but I’m more of a plain text kind of person. Also it adds to the length. I wonder if putting a separate document would make more sense; that would also help with the length.
There’s a simple reason all the current hashes end in a or q: the hash is 256 bits, the base32 encoding chops that into groups of 5 bits, and 256 isn’t divisible by 5. The last character of the base32 encoding just has that left-over single bit (256 mod 5 = 1).
So I agree with #3 below, but do you have a source for #1, #2 or #4? I would expect any lack of variability in any part of a hash function’s output would make it more vulnerable to attacks, so designers of hash functions would want to make the whole output vary as much as possible.
Other than the divisible-by-5 thing, my current intuition is it doesn’t matter what part you take.
Hash Structure: Hashes are typically designed so that their outputs have specific statistical properties. The first few characters often have more entropy or variability, meaning they are less likely to have patterns. The last characters may not maintain this randomness, especially if the encoding method has a tendency to produce less varied endings.
Collision Resistance: When using hashes, the goal is to minimize the risk of collisions (different inputs producing the same output). By using the first few characters, you leverage the full distribution of the hash. The last characters may not distribute in the same way, potentially increasing the likelihood of collisions.
Encoding Characteristics: Base32 encoding has a specific structure and padding that might influence the last characters more than the first. If the data being hashed is similar, the last characters may be more similar across different hashes.
Use Cases: In many applications (like generating unique identifiers), the beginning of the hash is often the most informative and varied. Relying on the end might reduce the uniqueness of generated identifiers, especially if a prefix has a specific context or meaning.
@prologic@twtxt.net I saw those, yes. I tried using yarnc
, and it would work for a simple twtxt. Now, for a more convoluted one it truly becomes a nightmare using that tool for the job. I know there are talks about changing this hash, so this might be a moot point right now, but it would be nice to have a tool that:
- Would calculate the hash of a twtxt in a file.
- Would calculate all hashes on a
twtxt.txt
(local and remote).
Again, something lovely to have after any looming changes occur.
@movq@www.uninformativ.de I didn’t run the command as you recommended, but, I wiped things once more, and ran jenny -f
, and this time got:
david@arrakis:~$ jenny -f
Fetching archived feed https://anthony.buc.ci/user/abucci/twtxt.txt/1 (configured as abucci, https://anthony.buc.ci/user/abucci/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2024-04.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://darch.dk/twtxt-archive.txt (configured as soren, https://darch.dk/twtxt.txt)
Fetching archived feed https://www.uninformativ.de/twtxt-old_2024-04-21_6v47cua.txt (configured as movq, https://www.uninformativ.de/twtxt.txt)
Fetching archived feed https://twtxt.net/user/prologic/twtxt.txt/1 (configured as prologic, https://twtxt.net/user/prologic/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2024-03.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://www.uninformativ.de/twtxt-old_2022-12-21_2us6qbq.txt (configured as movq, https://www.uninformativ.de/twtxt.txt)
Fetching archived feed https://twtxt.net/user/prologic/twtxt.txt/2 (configured as prologic, https://twtxt.net/user/prologic/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2024-02.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://www.uninformativ.de/twtxt-old_2022-01-14_ew5gzca.txt (configured as movq, https://www.uninformativ.de/twtxt.txt)
Fetching archived feed https://twtxt.net/user/prologic/twtxt.txt/3 (configured as prologic, https://twtxt.net/user/prologic/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2024-01.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://www.uninformativ.de/twtxt-old_2021-12-23_f6y65bq.txt (configured as movq, https://www.uninformativ.de/twtxt.txt)
Fetching archived feed https://twtxt.net/user/prologic/twtxt.txt/4 (configured as prologic, https://twtxt.net/user/prologic/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2023-12.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://www.uninformativ.de/twtxt-old_2021-12-04_e4x7yba.txt (configured as movq, https://www.uninformativ.de/twtxt.txt)
Fetching archived feed https://twtxt.net/user/prologic/twtxt.txt/5 (configured as prologic, https://twtxt.net/user/prologic/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2023-11.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://www.uninformativ.de/twtxt-old_2021-11-18_42tjxba.txt (configured as movq, https://www.uninformativ.de/twtxt.txt)
Fetching archived feed https://twtxt.net/user/prologic/twtxt.txt/6 (configured as prologic, https://twtxt.net/user/prologic/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2023-10.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://www.uninformativ.de/twtxt-old_2021-11-08_i2wnvaa.txt (configured as movq, https://www.uninformativ.de/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2023-09.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://www.uninformativ.de/twtxt-old_2021-10-23_kvwn5oa.txt (configured as movq, https://www.uninformativ.de/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2023-08.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://www.uninformativ.de/twtxt-old_2021-10-11_mljudaa.txt (configured as movq, https://www.uninformativ.de/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2023-07.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://www.uninformativ.de/twtxt-old_2021-09-22_5mkqwua.txt (configured as movq, https://www.uninformativ.de/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2023-06.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://www.uninformativ.de/twtxt-old_2021-07-27_xcnzmlq.txt (configured as movq, https://www.uninformativ.de/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2023-05.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://www.uninformativ.de/twtxt-old_2021-06-16_mtedqya.txt (configured as movq, https://www.uninformativ.de/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2023-04.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://www.uninformativ.de/twtxt-old_2021-04-29_z7lvzja.txt (configured as movq, https://www.uninformativ.de/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2023-03.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://www.uninformativ.de/twtxt-old_2021-03-19_xjabvhq.txt (configured as movq, https://www.uninformativ.de/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2023-02.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://www.uninformativ.de/twtxt-old_2021-02-24_te4a6oa.txt (configured as movq, https://www.uninformativ.de/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2023-01.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://www.uninformativ.de/twtxt-old_2021-01-26_qxgigma.txt (configured as movq, https://www.uninformativ.de/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2022-12.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://www.uninformativ.de/twtxt-old_2020-12-13_igfnala.txt (configured as movq, https://www.uninformativ.de/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2022-11.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2022-10.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2022-09.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2022-08.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2022-07.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2022-06.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2022-05.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2022-04.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2022-03.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2022-02.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2022-01.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2021-12.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2021-11.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2021-10.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2021-09.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2021-08.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2021-07.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2021-06.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2021-05.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2021-04.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2021-03.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2021-02.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2021-01.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Fetching archived feed https://lyse.isobeef.org/twtxt-2020-12.txt (configured as lyse, https://lyse.isobeef.org/twtxt.txt)
Notice that @prologic@twtxt.net’s /6
is there. I found the twtxt then. Kind of odd it didn’t show before.
More:
Subject: The [tag URI scheme](https://en.wikipedia.org/wiki/Tag_URI_scheme) looks interesting. I like that it human read- and writable. And since we already got the timestamp in the twtxt.txt it would be
somewhat trivial to parse. But there are still the issue with what the name/id should be... Maybe it doesn't have to bee that stick? Instead of using `tag:` as the prefix/protocol, it would more it clear
what we are talking about by using `in-reply-to:` (https://indieweb.org/in-reply-to) or `replyto:` similar to `mailto:` 1. `(reply:sorenpeter@darch.dk,2024-09-15T12:06:27Z)' 2.
`(in-reply-to:darch.dk/twtxt.txt,2024-09-15T12:06:27Z)' 2. `(replyto:http://darch.dk/twtxt.txt,2024-09-15T12:06:27Z)' I know it's longer that 7-11 characters, but it's self-explaining when looking at the
twtxt.txt in the raw, and the cases above can all be caught with this regex: `\([\w-]*reply[\w-]*\:` Is this something that would work?
Subject: The [tag URI scheme](https://en.wikipedia.org/wiki/Tag_URI_scheme) looks interesting. I like that it human read- and writable. And since we already got the timestamp in the twtxt.txt it would be
somewhat trivial to parse. But there are still the issue with what the name/id should be... Maybe it doesn't have to bee that stick? Instead of using `tag:` as the prefix/protocol, it would more it clear
what we are talking about by using `in-reply-to:` (https://indieweb.org/in-reply-to) or `replyto:` similar to `mailto:` 1. `(reply:sorenpeter@darch.dk,2024-09-15T12:06:27Z)` 2.
`(in-reply-to:darch.dk/twtxt.txt,2024-09-15T12:06:27Z)` 3. `(replyto:http://darch.dk/twtxt.txt,2024-09-15T12:06:27Z)` I know it's longer that 7-11 characters, but it's self-explaining when looking at the
twtxt.txt in the raw, and the cases above can all be caught with this regex: `\([\w-]*reply[\w-]*\:` Is this something that would work?
Notice the difference? Soren edited, and broke everything.
@mckinley@twtxt.net Thanks for the feedback.
- Yeah I agrees that nick sound not be part of syntax. Any valid URL to a twtxt.txt-file should be enough and is more clear, so it is not confused with a email (one of the the issues with webfinger and fedivese handles)
- I think any valid URL would work, since we are not bound to look for exact matches. Accepting both http and https as well as a gemni and gophe could all work as long as the path to the twtxt.txt is the same.
- My idea is that you quote the timestamp as it is in the original twtxt.txt that you are referring to, so you can do it by simply copy/pasting. Also what are the change that the same human will make two different posts within the same second?!
Regarding the whole cryptographic keys for identity, to me it seems like an unnecessary layer of complexity. If you move to a new house or city you tell people that you moved - you can do the same in a twtxt.txt. Just post something like “I move to this new URL, please follow me there!” I did that with my feeds at least twice, and you guys still seem to read my posts:)
The tag URI scheme looks interesting. I like that it human read- and writable. And since we already got the timestamp in the twtxt.txt it would be somewhat trivial to parse. But there are still the issue with what the name/id should be… Maybe it doesn’t have to bee that stick?
Instead of using tag:
as the prefix/protocol, it would more it clear what we are talking about by using in-reply-to:
(https://indieweb.org/in-reply-to) or replyto:
similar to mailto:
(reply:sorenpeter@darch.dk,2024-09-15T12:06:27Z)
(in-reply-to:darch.dk/twtxt.txt,2024-09-15T12:06:27Z)
(replyto:http://darch.dk/twtxt.txt,2024-09-15T12:06:27Z)
I know it’s longer that 7-11 characters, but it’s self-explaining when looking at the twtxt.txt in the raw, and the cases above can all be caught with this regex: \([\w-]*reply[\w-]*\:
Is this something that would work?
I was not suggesting to that everyone need to setup a working webfinger endpoint, but that we take the format of nick+(sub)domain as base for generating the hashed together with the message date and content.
If we omit the protocol prefix from the way we do things now will that not solve most of the problems? In the case of gemini://gemini.ctrl-c.club/~nristen/twtxt.txt
they also have a working twtxt.txt at https://ctrl-c.club/~nristen/twtxt.txt
… damn I just notice the gemini.
subdomain.
Okay what about defining a prefers protocol as part of the hash schema? so 1: https , 2: http 3: gemini 4: gopher ?
@prologic@twtxt.net Some criticisms and a possible alternative direction:
Key rotation. I’m not a security person, but my understanding is that it’s good to be able to give keys an expiry date and replace them with new ones periodically.
It makes maintaining a feed more complicated. Now instead of just needing to put a file on a web server (and scan the logs for user agents) I also need to do this. What brought me to twtxt was its radical simplicity.
Instead, maybe we should think about a way to allow old urls to be rotated out? Like, my metadata could somehow say that X used to be my primary URL, but going forward from date D onward my primary url is Y. (Or, if you really want to use public key cryptography, maybe something similar could be used for key rotation there.)
It’s nice that your scheme would add a way to verify the twts you download, but https is supposed to do that anyway. If you don’t trust https to do that (maybe you don’t like relying on root CAs?) then maybe your preferred solution should be reflected by your primary feed url. E.g. if you prefer the security offered by IPFS, then maybe an IPNS url would do the trick. The fact that feed locations are URLs gives some flexibility. (But then rotation is still an issue, if I understand ipns right.)
HTTP/2 differs from 1.x by becoming a binary protocol, it also multiplexes multiple channels over the same connection and has the ability to prefetch related content to the browser to lower the perceived latency.
HTTP/3 moves the binary protocol from HTTP/2 over to QUIC which is based on UDP instead of TCP. This makes it better suited to mobile or unstable networks where handling of transmission errors can be handled at a higher level.
@prologic@twtxt.net The headline is interesting and sent me down a rabbit hole understanding what the paper (https://aclanthology.org/2024.acl-long.279/) actually says.
The result is interesting, but the Neuroscience News headline greatly overstates it. If I’ve understood right, they are arguing (with strong evidence) that the simple technique of making neural nets bigger and bigger isn’t quite as magically effective as people say — if you use it on its own. In particular, they evaluate LLMs without two common enhancements, in-context learning and instruction tuning. Both of those involve using a small number of examples of the particular task to improve the model’s performance, and they turn them off because they are not part of what is called “emergence”: “an ability to solve a task which is absent in smaller models, but present in LLMs”.
They show that these restricted LLMs only outperform smaller models (i.e demonstrate emergence) on certain tasks, and then (end of Section 4.1) discuss the nature of those few tasks that showed emergence.
I’d love to hear more from someone more familiar with this stuff. (I’ve done research that touches on ML, but neural nets and especially LLMs aren’t my area at all.) In particular, how compelling is this finding that zero-shot learning (i.e. without in-context learning or instruction tuning) remains hard as model size grows.
@prologic@twtxt.net +1 for FrankenPHP. And built into caddy is also swell.
I think it is a good addition. Similar to how the Fraidycat RSS reader works. Fraidyc.at also support twtxt, but have not seen any updates since 2021…
A Nokia Art Jam organizada pelo @Polyducks@Polyducks é até 30 de maio!
Viddy, a modern watch(1) alternative with paging, visual diffs, and history: https://github.com/sachaos/viddy
cum catano!
@mckinley@twtxt.net, in your blog, I think a “line-heigh” of 1.5 (if I remember correctly you are setting it on the “body” on CSS) will make it more legible.
Ontem estive na CNN como representante da @d3 a comentar as desventuras da Worldcoin; é a partir da 1:04:00
https://cnnportugal.iol.pt/videos/cnn-fim-de-tarde-6-de-marco-de-2024/65e8f0ad0cf2c4edbc0d4bc1
Go 1.22.0 introduces a new experiment for range functions. Have you tried them out? What do you think it can make easier to accomplish?
The word forms is part two. In this one you want to find the first digit and last digit. Think searching ‘1’ - ‘9’
Esta mini-ficção em formato de artigo da Wikipédia delicia-me sempre que a volto a encontrar
MMAcevedo (Mnemonic Map/Acevedo), also known as Miguel, is the earliest executable image of a human brain. It is a snapshot of the living brain of neurology graduate Miguel Acevedo Álvarez (2010–2073), taken by researchers at the Uplift Laboratory at the University of New Mexico on August 1, 2031.
Estou algo apreensivo quanto aos planos da Mozilla para o fediverso, não sei o que acham
“Why Mozilla is betting on a decentralized social networking future”
This is some cool development for the go 1.22 standard http mux. Its adding the ability to have path vars and define methods for handlers. Also the errors are quite helpful if you have conflicting paths!
https://eli.thegreenplace.net/2023/better-http-server-routing-in-go-122/
@shreyan@twtxt.net probably ~1k up to 1.5k. One I found had 64G ram and 12C / 16T for 1.1k
So. Some bits.
i := fIndex(xs, 5.6)
Can also be
i := Index(xs, 5.6)
The compiler can infer the type automatically. Looks like you mention that later.
Also the infer is super smart.. You can define functions that take functions with generic types in the arguments. This can be useful for a generic value mapper for a repository
func Map[U,V any](rows []U, fn func(U) V) []V {
out := make([]V, len(rows))
for i := range rows { out = fn(rows[i]) }
return out
}
rows := []int{1,2,3}
out := Map(rows, func(v int) uint64 { return uint64(v) })
I am pretty sure the type parameters goes the other way with the type name first and constraint second.
func Foo[comparable T](xs T, s T) int
Should be
func Foo[T comparable](xs T, s T) int
2 BIT ENTER! 1 BIT LEAVES! — the THUNDERNOR
@prologic@twtxt.net That was exactly my thought at first too. but what do we put as the rel
for salty account? since it is decentralized we dont have a set URL for machines to key off. so for example take the standard response from okta:
# http GET https://example.okta.com/.well-known/webfinger resource==acct:bob
{
"links": [
{
"href": "https://example.okta.com/sso/idps/OKTA?login_hint=bob#",
"properties": {
"okta:idp:type": "OKTA"
},
"rel": "http://openid.net/specs/connect/1.0/issuer",
"titles": {
"und": "example"
}
}
],
"subject": "acct:bob"
}
It gives one link that follows the OpenID login. So the details are specific to the subject acct:bob
.
Mastodons response:
{
"subject": "acct:xuu@chaos.social",
"aliases": [
"https://chaos.social/@xuu",
"https://chaos.social/users/xuu"
],
"links": [
{
"rel": "http://webfinger.net/rel/profile-page",
"type": "text/html",
"href": "https://chaos.social/@xuu"
},
{
"rel": "self",
"type": "application/activity+json",
"href": "https://chaos.social/users/xuu"
},
{
"rel": "http://ostatus.org/schema/1.0/subscribe"
}
]
}
it supplies a profile page and a self
which are both specific to that account.
“(1) we don’t know what is going on in LLMs (2) it’s outlandish to say that LLMs have no understanding of the world” both claims cannot be true
$name$
and then dispatch the hashing or checking to its specific format.
Here is an example of usage:
func Example() {
pass := "my_pass"
hash := "my_pass"
pwd := passwd.New(
&unix.MD5{}, // first is preferred type.
&plainPasswd{},
)
_, err := pwd.Passwd(pass, hash)
if err != nil {
fmt.Println("fail: ", err)
}
// Check if we want to update.
if !pwd.IsPreferred(hash) {
newHash, err := pwd.Passwd(pass, "")
if err != nil {
fmt.Println("fail: ", err)
}
fmt.Println("new hash:", newHash)
}
// Output:
// new hash: $1$81ed91e1131a3a5a50d8a68e8ef85fa0
}
This shows how one would set a preferred hashing type and if the current version of ones password is not the preferred type updates it to enhance the security of the hashed password when someone logs in.
https://github.com/sour-is/go-passwd/blob/main/passwd_test.go#L33-L59
@lyse@lyse.isobeef.org im talking like some JS projects i have seen with 1-2G node_modules dirs. though yarn is quite vast in its modules because it does a LOOOOOOT of stuff in the background.
-1 for the negative on environment all that electricity uses. Still waiting on proof of stake.
It is also too overrun with Tech Bros scamming people to get rich quick.
It was a fun ride back when I first bought in. But I have since cached out for my lambos and such.
I’d hate to be the baby strapped to Voyager 1
@abucci@anthony.buc.ci Its not better than a Cat5e. I have had two versions of the device. The old ones were only 200Mbps i didn’t have the MAC issue but its like using an old 10baseT. The newer model can support 1Gbps on each port for a total bandwidth of 2Gbps.. i typically would see 400-500Mbps from my Wifi6 router. I am not sure if it was some type of internal timeout or being confused by switching between different wifi access points and seeing the mac on different sides.
Right now I have my wifi connected directly with a cat6e this gets me just under my providers 1.3G downlink. the only thing faster is plugging in directly.
MoCA is a good option, they have 2.5G models in the same price range as the 1G Powerline models BUT, only if you have the coax in wall already.. which puts you in the same spot if you don’t. You are for sure going to have an outlet in every room of the house by code.
Huh… Nope.
HTTP/1.1 200 OK
Content-Length: 407
Content-Type: text/calendar
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: ETag
Permissions-Policy: interest-cohort=()
Content-Security-Policy: default-src 'none'; sandbox
Referrer-Policy: same-origin
Vary: Authorization
BEGIN:VCALENDAR
VERSION:2.0;2.0
PRODID:SandCal
CALSCALE:GREGORIAN
BEGIN:VEVENT
DTSTAMP:20220822T180903Z
UID:bb63bfbd-623e-4805-b11b-3181d96375e6
DTSTART;TZID=America/Chicago:20220827T000000
CREATED:20220822T180903Z
LAST-MODIFIED:20220822T180903Z
LOCATION:https://meet.jit.si/Yarn.social
SUMMARY:Yarn Call
RRULE:FREQ=WEEKLY
DTEND;TZID=America/Chicago:20220827T010000
END:VEVENT
END:VCALENDAR
Progress! so i have moved into working on aggregates. Which are a grouping of events that replayed on an object set the current state of the object. I came up with this little bit of generic wonder.
type PA[T any] interface {
event.Aggregate
*T
}
// Create uses fn to create a new aggregate and store in db.
func Create[A any, T PA[A]](ctx context.Context, es *EventStore, streamID string, fn func(context.Context, T) error) (agg T, err error) {
ctx, span := logz.Span(ctx)
defer span.End()
agg = new(A)
agg.SetStreamID(streamID)
if err = es.Load(ctx, agg); err != nil {
return
}
if err = event.NotExists(agg); err != nil {
return
}
if err = fn(ctx, agg); err != nil {
return
}
var i uint64
if i, err = es.Save(ctx, agg); err != nil {
return
}
span.AddEvent(fmt.Sprint("wrote events = ", i))
return
}
This lets me do something like this:
a, err := es.Create(ctx, r.es, streamID, func(ctx context.Context, agg *domain.SaltyUser) error {
return agg.OnUserRegister(nick, key)
})
I can tell the function the type being modified and returned using the function argument that is passed in. pretty cray cray.
+1
with resolving inconsistent graph preferences, does the portion of non-uniquely resolvable preferences shrink with the number of options? in other words: for the set 𝓖_n of all graphs with n nodes, and the set U(𝓖_n) of those graphs with a unique path-graph with a smallest graph-edit distance, is |U(𝓖_n)|/𝓖n<|U(𝓖{n+1})|/|𝓖_{n+1}|?
“i’ll stop reading at 1:30” this is your internal agents coordinating
three aspects of feedback loops: 1. speed (how quickly do you get feedback); 2. thickness (how much information do you get about your performance); 3. signal (how related is that feedback to your performance)
@novaburst@twt.nfld.uk I doubt there will ever be a 2.0 … It may end up like java and they strip off the 1.
#!/bin/sh
# Validate environment
if ! command -v msgbus > /dev/null; then
printf "missing msgbus command. Use: go install git.mills.io/prologic/msgbus/cmd/msgbus@latest"
exit 1
fi
if ! command -v salty > /dev/null; then
printf "missing salty command. Use: go install go.mills.io/salty/cmd/salty@latest"
exit 1
fi
if ! command -v salty-keygen > /dev/null; then
printf "missing salty-keygen command. Use: go install go.mills.io/salty/cmd/salty-keygen@latest"
exit 1
fi
if [ -z "$SALTY_IDENTITY" ]; then
export SALTY_IDENTITY="$HOME/.config/salty/$USER.key"
fi
get_user () {
user=$(grep user: "$SALTY_IDENTITY" | awk '{print $3}')
if [ -z "$user" ]; then
user="$USER"
fi
echo "$user"
}
stream () {
if [ -z "$SALTY_IDENTITY" ]; then
echo "SALTY_IDENTITY not set"
exit 2
fi
jq -r '.payload' | base64 -d | salty -i "$SALTY_IDENTITY" -d
}
lookup () {
if [ $# -lt 1 ]; then
printf "Usage: %s nick@domain\n" "$(basename "$0")"
exit 1
fi
user="$1"
nick="$(echo "$user" | awk -F@ '{ print $1 }')"
domain="$(echo "$user" | awk -F@ '{ print $2 }')"
curl -qsSL "https://$domain/.well-known/salty/${nick}.json"
}
readmsgs () {
topic="$1"
if [ -z "$topic" ]; then
topic=$(get_user)
fi
export SALTY_IDENTITY="$HOME/.config/salty/$topic.key"
if [ ! -f "$SALTY_IDENTITY" ]; then
echo "identity file missing for user $topic" >&2
exit 1
fi
msgbus sub "$topic" "$0"
}
sendmsg () {
if [ $# -lt 2 ]; then
printf "Usage: %s nick@domain.tld <message>\n" "$(basename "$0")"
exit 0
fi
if [ -z "$SALTY_IDENTITY" ]; then
echo "SALTY_IDENTITY not set"
exit 2
fi
user="$1"
message="$2"
salty_json="$(mktemp /tmp/salty.XXXXXX)"
lookup "$user" > "$salty_json"
endpoint="$(jq -r '.endpoint' < "$salty_json")"
topic="$(jq -r '.topic' < "$salty_json")"
key="$(jq -r '.key' < "$salty_json")"
rm "$salty_json"
message="[$(date +%FT%TZ)] <$(get_user)> $message"
echo "$message" \
| salty -i "$SALTY_IDENTITY" -r "$key" \
| msgbus -u "$endpoint" pub "$topic"
}
make_user () {
mkdir -p "$HOME/.config/salty"
if [ $# -lt 1 ]; then
user=$USER
else
user=$1
fi
identity_file="$HOME/.config/salty/$user.key"
if [ -f "$identity_file" ]; then
printf "user key exists!"
exit 1
fi
# Check for msgbus env.. probably can make it fallback to looking for a config file?
if [ -z "$MSGBUS_URI" ]; then
printf "missing MSGBUS_URI in environment"
exit 1
fi
salty-keygen -o "$identity_file"
echo "# user: $user" >> "$identity_file"
pubkey=$(grep key: "$identity_file" | awk '{print $4}')
cat <<- EOF
Create this file in your webserver well-known folder. https://hostname.tld/.well-known/salty/$user.json
{
"endpoint": "$MSGBUS_URI",
"topic": "$user",
"key": "$pubkey"
}
EOF
}
# check if streaming
if [ ! -t 1 ]; then
stream
exit 0
fi
# Show Help
if [ $# -lt 1 ]; then
printf "Commands: send read lookup"
exit 0
fi
CMD=$1
shift
case $CMD in
send)
sendmsg "$@"
;;
read)
readmsgs "$@"
;;
lookup)
lookup "$@"
;;
make-user)
make_user "$@"
;;
esac
;-) I seem to remember there being g a script that checks for 1.17. Maybe that is only on make preflight
@prologic@twtxt.net yarn builds in 1.18!
I prefer ::1
niplav attempting to get cancelled by the physics community: attempt 1
Wow. I’m paying about 100 USD for my cable internet. Hard to estimate since its part of a tvd bundle. But it is 1.2Gbit down and 40Mbit up. And speed tests at that on the regular. The new house will have FTTH gigabit for 80ish.
Do they have Starlink beta down there yet?
i think that every language should have a unary - and + operator, and that those should be idempotent. sign flipping should be done by multiplication with -1.
@fastidious@arrakis.netbros.com +1 …Now just a way to come up with the $20 per twt to store the data.
🧮 USERS:1 FEEDS:6 TWTS:714 ARCHIVED:128102 CACHE:14765 FOLLOWERS:26 FOLLOWING:46
🧮 USERS:1 FEEDS:6 TWTS:713 ARCHIVED:127922 CACHE:14685 FOLLOWERS:26 FOLLOWING:46
🧮 USERS:1 FEEDS:6 TWTS:711 ARCHIVED:127716 CACHE:14579 FOLLOWERS:26 FOLLOWING:46
🧮 USERS:1 FEEDS:6 TWTS:708 ARCHIVED:127427 CACHE:14401 FOLLOWERS:26 FOLLOWING:46
🧮 USERS:1 FEEDS:6 TWTS:706 ARCHIVED:127220 CACHE:14272 FOLLOWERS:25 FOLLOWING:46
🧮 USERS:1 FEEDS:6 TWTS:705 ARCHIVED:126932 CACHE:13951 FOLLOWERS:25 FOLLOWING:46
🧮 USERS:1 FEEDS:6 TWTS:701 ARCHIVED:126616 CACHE:13737 FOLLOWERS:25 FOLLOWING:45
🧮 USERS:1 FEEDS:6 TWTS:698 ARCHIVED:126308 CACHE:13511 FOLLOWERS:25 FOLLOWING:45
🧮 USERS:1 FEEDS:6 TWTS:691 ARCHIVED:126044 CACHE:13187 FOLLOWERS:25 FOLLOWING:45
🧮 USERS:1 FEEDS:6 TWTS:688 ARCHIVED:125695 CACHE:12698 FOLLOWERS:25 FOLLOWING:49
@fastidious@arrakis.netbros.com (#twksmyq) IPv6 because localhost -> ::1 is preferred on linux over ol’ 127.0.0.1
Now this is very useful.. it means when yarn is doing an HTTP request to itself its not closing the connection. that could mean a http.Response Body is not getting closed.
🧮 USERS:1 FEEDS:6 TWTS:676 ARCHIVED:125180 CACHE:10027 FOLLOWERS:25 FOLLOWING:46
🧮 USERS:1 FEEDS:6 TWTS:668 ARCHIVED:124723 CACHE:13955 FOLLOWERS:25 FOLLOWING:46
🧮 USERS:1 FEEDS:6 TWTS:662 ARCHIVED:124594 CACHE:13671 FOLLOWERS:24 FOLLOWING:45
🧮 USERS:1 FEEDS:6 TWTS:661 ARCHIVED:124463 CACHE:12661 FOLLOWERS:24 FOLLOWING:45
🧮 USERS:1 FEEDS:6 TWTS:660 ARCHIVED:124286 CACHE:10259 FOLLOWERS:24 FOLLOWING:45
🧮 USERS:1 FEEDS:6 TWTS:657 ARCHIVED:124059 CACHE:8773 FOLLOWERS:23 FOLLOWING:45
🧮 USERS:1 FEEDS:6 TWTS:651 ARCHIVED:123454 CACHE:6499 FOLLOWERS:23 FOLLOWING:45
🧮 USERS:1 FEEDS:6 TWTS:44582 ARCHIVED:122836 CACHE:10043 FOLLOWERS:23 FOLLOWING:45
@darch@twtxt.net
Getting this when trying to use it:
error executing template timeline: template: timeline:131:43: executing "twt" at <formatForDateTime>: wrong number of args for formatForDateTime: want 2 got 1
🧮 USERS:1 FEEDS:6 TWTS:44581 ARCHIVED:122474 CACHE:9991 FOLLOWERS:23 FOLLOWING:45
🧮 USERS:1 FEEDS:6 TWTS:44580 ARCHIVED:122069 CACHE:11727 FOLLOWERS:23 FOLLOWING:45
🧮 USERS:1 FEEDS:6 TWTS:44578 ARCHIVED:120748 CACHE:10544 FOLLOWERS:23 FOLLOWING:45
🧮 USERS:1 FEEDS:6 TWTS:44574 ARCHIVED:120245 CACHE:6137 FOLLOWERS:23 FOLLOWING:45
🧮 USERS:1 FEEDS:6 TWTS:44571 ARCHIVED:117826 CACHE:19109 FOLLOWERS:23 FOLLOWING:45
🧮 USERS:1 FEEDS:6 TWTS:44569 ARCHIVED:115777 CACHE:17622 FOLLOWERS:23 FOLLOWING:45
+1
🧮 USERS:1 FEEDS:6 TWTS:44562 ARCHIVED:113664 CACHE:14484 FOLLOWERS:23 FOLLOWING:45
🧮 USERS:1 FEEDS:6 TWTS:44561 BLOGS:3 ARCHIVED:108163 CACHE:15398 FOLLOWERS:23 FOLLOWING:44
🧮 USERS:1 FEEDS:6 TWTS:44560 BLOGS:3 ARCHIVED:107759 CACHE:15365 FOLLOWERS:23 FOLLOWING:44
🧮 USERS:1 FEEDS:6 TWTS:44559 BLOGS:3 ARCHIVED:107383 CACHE:15350 FOLLOWERS:23 FOLLOWING:44
🧮 USERS:1 FEEDS:6 TWTS:44558 BLOGS:3 ARCHIVED:106992 CACHE:15325 FOLLOWERS:23 FOLLOWING:44
🧮 USERS:1 FEEDS:6 TWTS:44557 BLOGS:3 ARCHIVED:106371 CACHE:15079 FOLLOWERS:23 FOLLOWING:44
🧮 USERS:1 FEEDS:6 TWTS:44555 BLOGS:3 ARCHIVED:106018 CACHE:14922 FOLLOWERS:23 FOLLOWING:44
My nutritional supplements aim should be:
- 1 or 1.5 cups of lentils (or any beans you might like better).
- 2 or 2.5 cups of bitter greens.
- 1 cup of your favourite protein (or an egg), grilled, or fried with a little of olive oil.
- 1 or 2 tomatoes, or a handful if of the cherry type.
- No added sugars. If it is sweet, make it have fibre.
- No added salt (or very little and ionised), as salt is everywhere.
Related, I tried wild rice for the first time yesterday. It was different, in a good way.
🧮 USERS:1 FEEDS:6 TWTS:44554 BLOGS:3 ARCHIVED:105912 CACHE:14907 FOLLOWERS:23 FOLLOWING:44
Standby BIG-IP F5s upgraded to TMOS 16.1 (LTS). All their pairs (now on standby) will be upgraded on Wednesday. Just giving the TMOS some time to settle down, and feel at home. Hahahaha!
🧮 USERS:1 FEEDS:6 TWTS:44553 BLOGS:3 ARCHIVED:105763 CACHE:14865 FOLLOWERS:23 FOLLOWING:44
🧮 USERS:1 FEEDS:6 TWTS:44552 BLOGS:3 ARCHIVED:105647 CACHE:14845 FOLLOWERS:23 FOLLOWING:44
🧮 USERS:1 FEEDS:6 TWTS:44551 BLOGS:3 ARCHIVED:105499 CACHE:14827 FOLLOWERS:23 FOLLOWING:44
🧮 USERS:1 FEEDS:6 TWTS:44550 BLOGS:3 ARCHIVED:105434 CACHE:14813 FOLLOWERS:23 FOLLOWING:44
🧮 USERS:1 FEEDS:6 TWTS:44548 BLOGS:3 ARCHIVED:105327 CACHE:14831 FOLLOWERS:22 FOLLOWING:44
🧮 USERS:1 FEEDS:6 TWTS:44547 BLOGS:3 ARCHIVED:105017 CACHE:14595 FOLLOWERS:22 FOLLOWING:44
🧮 USERS:1 FEEDS:6 TWTS:44546 BLOGS:3 ARCHIVED:104831 CACHE:14471 FOLLOWERS:22 FOLLOWING:44