fib(35) doesn't regress too badly as I continue to evolve the language.
@prologic@twtxt.net Not bad for a start, ey! Looking forward to see you going down these rabbit holes and opening one can of worms after the other. :ā-D Very, very impressive, hats off to you. :-)
@shinyoukai@neko.laidback.moe Because you might not want to commit all changed files in a single commit. I very often make use of this and create several commits. In fact, I like to git add --patch to interactively select which parts of a file go in the next commit. This happens most likely when refactoring during a feature implementation or bug fix. I couldnāt live without that anymore. :-)
If you have a much more organized way of working where this does not come up, you can just git commit --all to include all changed files in the next commit without git adding them first. But new files still have to be git added manually once.
os.UserConfigDir() up until a few seconds ago! I always implemented that myself.
@shinyoukai@neko.laidback.moe Yeah, they donāt truly support XDG. In fact, I looked in the Go stdlib source code to notice all the differences and shortcomings.
$HOME is not specified it tries to resolve the user's home directory by user.Current().HomeDir. Maybe that's overkill, I have to check the XDG spec.
Ok, the standard library implementation is wonky at best, at least in regards to XDG, because it really doesnāt implement it properly. https://github.com/golang/go/issues/62382 I stick to my own code then. It doesnāt properly support anything else than Linux or Unixes that use XDG, but personally, I donāt care about them anyway. And the cross-platform situation is a giant mess. Unsurprisingly.
@movq@www.uninformativ.de Thanks! Iāll have a look at SnipMate. Currently, Iām (mis)using the abbreviation mechanism to expand a code snippet inplace, e.g.
autocmd FileType go inoreab <buffer> testfunc func Test(t *testing.T) {<CR>}<ESC>k0wwi
or this monstrosity:
autocmd FileType go inoreab <buffer> tabletest for _, tt := range []struct {<CR> name string<CR><CR><BS>}{<CR> {<CR> name: "",<CR><BS>},<CR><BS>} {<CR> t.Run(tt.name, func(t *testing.T) {<CR><CR>})<CR><BS>}<ESC>9ki<TAB>
But this of course has the disadvantage that I still have to remove the last space or tab to trigger the expansion by hand again. Itās a bit annoying, but better than typing it out by hand.
The tt URLs View now automatically selects the first URL that I probably are going to open. In decreasing order, the URL types are:
- markdown media URLs (images, videos, etc.)
- markdown or plaintext URLs
- subjects
- mentions
I might differentiate between mentions of subscribed and unsubscribed feeds in the future. The odds of opening a new feed over an already existing one are higher.
@zvava@twtxt.net By hashing definition, if you edit your message, it simply becomes a new message. Itās just not the same message anymore. At least from a technical point of view. As a human, personally I disagree, but thatās what Iām stuck with. Thereās no reliable way to detect and ācorrectā for that.
Storing the hash in your database doesnāt prevent you from switching to another hashing implementation later on. As of now, message creation timestamps earlier than some magical point in time use twt hash v1, messages on or after that magical timestamp use twt hash v2. So, a message either has a v1 or a v2 hash, but not both. At least one of them is never meaningful.
Once you āupgradeā your database schema, you can check for stored messages from the future which should have been hashed using v2, but were actually v1-hashed and simply fix them.
If there will ever be another addressing scheme, you could reuse the existing hash column if it supersedes the v1/v2 hashes. Otherwise, a new column might be useful, or perhaps no column at all (looking at location-based addressing or how it was called). The old v1/v2 hashes are still needed for all past conversation trees.
In my opinion, always recalculating the hashes is a big waste of time and energy. But if it serves you well, then go for it.
@shinyoukai@neko.laidback.moe Nah itās more like thereās a lot of repeated code, because when you go from source language to intermediate representation to machine code, well you just end up writing a lot of the same patterns over and over again. I need to dedupe this I think.
@prologic@twtxt.net Not even entirely sure how I did it myself, but likely a lucky combination of the new tail swirl, the legs closer to the screen being bigger and the head looking slightly to the side (eye & ear position), with bottom part of the hair, going behind the snout. The white is just an outline, around most of my works, so I donāt think that plays a part.
@movq@www.uninformativ.de From 2:50 PM to 3:23 PM AEST (+10 UTC) there was an outage. Everything went āupā on Down Detector, my EU region went offline, numerous sites were unavailable, and so on. Basically everything to/from the EU appeared to basically go kaput.
@lyse@lyse.isobeef.org These tables get shuffled around every time your OS switches to another process. Itās crazy that so much is going on behind the scenes.
@kiwu@twtxt.net Assembly is usually the most low-level programming language that you can get. Typical programming languages like Python or Go are a thick layer of abstraction over what the CPU actually does, but with Assembler you get to see it all and you get full control. (With lots of caveats and footnotes. š )
Iām interested in the boot process, i.e. what exactly happens when you turn on your computer. In that area, using Assembler is a must, because you really need that fine-grained control here.
@kiwu@twtxt.net Iām doing great, howāre ya going? Just two more days and then I never have to work anymore. In this year.
I just baked two trays of gingerbread. One definitely good one and another experiment.
This morning was also super pretty: https://lyse.isobeef.org/morgensonne-2025-12-19/
I finished all 12 days of Advent of Code 2025! #AdventOfCode https://adventofcode.com ā did it in my own language, mu (Go/Python-ish, dynamic, int/bool/string, no floats/bitwise). Found a VM bug, fixed it, and the self-hosted mu compiler/VM (written in mu, host in Go) carried me through. š„³
I just completed āPrinting Departmentā - Day 4 - Advent of Code 2025 #AdventOfCode https://adventofcode.com/2025/day/4 ā Again, Iām doing this in mu, a Go(ish) / Python(ish) dynamic langugage that I had to design and build first which has very few builtins and only a handful of types (ints, no flots). š¤£
I just completed āLobbyā - Day 3 - Advent of Code 2025 #AdventOfCode https://adventofcode.com/2025/day/3 ā Again, Iām doing this in mu, a Go(ish) / Python(ish) dynamic langugage that I had to design and build first which has very few builtins and only a handful of types (ints, no flots). š¤£
Ahh thatās because I forgot to call main() at the end of the source file. mu is a bit of a dynamic programming language, mix of Go(ish) and Python(ish).
$ ./bin/mu examples/aoc2025/day1.mu
Execution failed: undefined variable readline
@shinyoukai@neko.laidback.moe is that https://github.com/owncloud/ocis (Go based, instead of PHP š¤®)?
Fishing
ā Read more
@prologic@twtxt.net Here you go:
(LTT = āLinus Tech Tipsā, thatās the host.)
LTT: There was a recent thing from a major tech company, where developers were asked to say how many lines of code they wrote ā and if it wasnāt enough, they were terminated. And there was someone here that was extremely upset about that approach to measuring productivity, becauseā
Torvalds: Oh yeah, no, you shouldnāt even be upset. At that point, thatās just incompetence. Anybody who thinks thatās a valid metric is too stupid to work at a tech company.
LTT: You do know who you just said that about, right?
Torvalds: No.
LTT: Oh. Uh, he was a prominent figure in the, uh, improved efficiency of the US government recently.
Torvalds: Oh. Apparently I was spot on.
@prologic@twtxt.net Ah, shit, you might be right. You can even buy these slot plates on Amazon. I didnāt even think to check Amazon, I went straight to eBay and tried to find it there, because I thought āitās so old, nobody is going to use that anymore, I need to buy second-handā. š¤¦š¤¦š¤¦
It really shows that I built my last PC so long ago ⦠I know next to nothing about current hardware. š¢
@prologic@twtxt.net Well, to be fair, if you show me any picture of a penguin (or in fact any bird), Iāll go āawwwwwww šā for a little while. š
Day 6 of AoC, and Iām all caught up. 12 puzzles down, 12 more to go!
@shinyoukai@neko.laidback.moe yeah, thatās the only reason why I use sub-domains when trying anything federated (I believe Matrix has the same problem), in case things didnāt go as planned I can just migrate and take it down.
@lyse@lyse.isobeef.org no wonder I picked that cake (albeit coincidentally), I adore almonds, and hazelnuts! Your teammates are absolutely amazing, dude! A very nice project farewell! On leaving places I have a small anecdote.
I know someone who on 3 February 2004 left his job to go elsewhere. At the time his teammates threw a party, and gave him a very nice portable storage. Twenty days later, he returned, and jokingly they asked him for the storage, and money spent on farewell party back. I heard, from a close source, that he gave them his middle finger, but donāt quote me on that. ššš
The most interesting part about mu is that the language is actually self-hosted and written in itself. There is a stage zero compound written and go on a stage one compiler written in mu
Thinking about doing Advent of Code in my own tiny language mu this year.
mu is:
- Dynamically typed
- Lexically scoped with closures
- Has a Go-like curly-brace syntax
- Built around lists, maps, and first-class functions
Key syntax:
- Functions use
fnand braces:
fn add(a, b) {
return a + b
}
- Variables use
:=for declaration and=for assignment:
x := 10
x = x + 1
- Control flow includes
if/elseandwhile:
if x > 5 {
println("big")
} else {
println("small")
}
while x < 10 {
x = x + 1
}
- Lists and maps:
nums := [1, 2, 3]
nums[1] = 42
ages := {"alice": 30, "bob": 25}
ages["bob"] = ages["bob"] + 1
Supported types:
int
bool
string
list
map
fn
nil
mu feels like a tiny little Go-ish, Python-ish language ā curious to see how far I can get with it for Advent of Code this year. š
@prologic@twtxt.net pretty cool! I like these, wish there was a way (I am sure there is, but not for tourists) to go to the top. :-)
Advent of Code 2025 starts tomorrow. š„³š
This year, Iām going to use Python 1 on SuSE Linux 6.4, writing the code on my trusty old Pentium 133 with its 64 MB of RAM. No idea if that old version of Python will be fast enough for later puzzles. Weāll see.
Thatās going to be most of our holidays next year 𤣠Mostly because we bought a van to go āglampingā about the country š
@movq@www.uninformativ.de You donāt go on holidays anywhere? š§
@kiwu@twtxt.net It also greatly depends on what kind of videos you plan to record. When you go, letās say, diving, the specs need to be probably more suited to that type of environment. What about zoom, macro shots, wide landscapes, and so on? When typically mounted on a tripod, Iād say builtin image stabilization is not required, but for more action shots, this is fairly important to not get sea sick. :-)
Iāve got a Nikon Coolpix S9300. I typically only take photos, but it also works for the occasional video. Free hand moves are quite difficult, but when mounted to a tripod, this is not too shabby. Thereās absolutely no way around a (makeshift) tridpod when zooming in, though. The audio is definitely not the best, especially wind destroys everything. If I recorded more video, I would certainly want to have an external microphone.
@prologic@twtxt.net Hmm. š¤ Well, I donāt run that server myself, so I canāt peek into the logs to see whatās going wrong ⦠š„“
Finally!! I can go to sleep!
config.yaml, and 4 lines Caddyfile, and you will see how easy it is.
@shinyoukai@neko.laidback.moe there you go! What I am trying to say is, if @prologic@twtxt.net truly wants to be able to diagnose something as difficult to diagnose as ActivityPub, he ought to run his own. There is no workaround.
@aelaraji@aelaraji.com I think Iāll just end up using the Official CrowdSec Go library š¤
@prologic@twtxt.net The main thing that I tought of is that whomever is abusing your services must be a well known actor (by range/set of IPs) that got reported by other Crowdsec users. So to my simpletonās understanding, your reverse-proxy/web server passes the requests by crowdsec for processing, they get banned for $N hours if the source has already been blacklisted by the community or violates any of a set of behavior base rules (and even more hours for repeat offenders); otherwise the requests/responses go as per usual. Not sure if I got things right but this might help paint a better picture of the process.
This caveman is getting too old for the Internet⦠š It took me 1 hrs and 50 mins to catch up with whatās been going on my feed.
When I try to login to PayPal I now see:
Please enable JS and disable any ad blocker
Hereās the thing. PayPal takes fees from transactions and payments received and sent.
I have very right not have ads shoved in my face for something that isnāt actually free in the first place and costs money to use. If PayPal would like to continue to piss off folks me like, then Iāll happily close my PayPal account and go somewhere else that doesnāt shove ads in my face and consume 30-40% of my Internet bandwidth on useless garbage/crap.
Iāve once again brought up a Gitea instance on my server space, but there are two highlights here:
- No self-registration (accounts are tied to the e-mail server, which is in turn tied to the system accounts)
- Going beyond the landing page requires to be logged in, no excuses. (It also could scare the AI crawlers to oblivion, avoiding Anubis at that)
Thatās it.
twtxt.net) was being hammered by something at a request rate of 30 req/s (there are global rate limits in place, but still...). The culprit? Turned out to be a particular IP 43.134.51.191 and after looking into who own s that IP I discovered it was yet-another-bad-customer-or-whatever from Tencent, so that entire network (ASN) is now blocked from my Edge:
@prologic@twtxt.net Time to make a new internet. Maybe one that intentionally doesnāt āscaleā and remains slow (on both ends) so itās harder to overload in this manner, harder to abuse for tracking your every move, ⦠Got any of those 56k modems left?
(Iām half-joking. āMake The Internet Expensive Againā like it was in the 1990ies and some of these problems might go away. Disclaimer: I didnāt have my coffee yet. š )
Fark me š¤¦āāļø I woke up quite late today (after a long night helping/assisting with a Mainframe migration last night fork work) to abusive traffic and my alerts going off. The impact? My pod (twtxt.net) was being hammered by something at a request rate of 30 req/s (there are global rate limits in place, but stillā¦). The culprit? Turned out to be a particular IP 43.134.51.191 and after looking into who own s that IP I discovered it was yet-another-bad-customer-or-whatever from Tencent, so that entire network (ASN) is now blocked from my Edge:
+# Who: Tentcent
+# Why: Bad Bots
+132203
Total damage?
$ caddy-log-formatter twtxt.net.log | cut -f 1 -d ' ' | sort | uniq -c | sort -r -n -k 1 | head -n 5
61371 43.134.51.191
402 159.196.9.199
121 45.77.238.240
8 106.200.1.116
6 104.250.53.138
61k reqs over an hour or so (before I noticed), bunch of CPU time burned, and useless waste of my fucking time.
All my newly added test cases failed, that movq thankfully provided in https://git.mills.io/yarnsocial/twtxt.dev/pulls/28#issuecomment-20801 for the draft of the twt hash v2 extension. The first error was easy to see in the diff. The hashes were way too long. Youāve already guessed it, I had cut the hash from the twelfth character towards the end instead of taking the first twelve characters: hash[12:] instead of hash[:12].
After fixing this rookie mistake, the tests still all failed. Hmmm. Did I still cut the wrong twelve characters? :-? I even checked the Go reference implementation in the document itself. But it read basically the same as mine. Strange, what the heck is going on here?
Turns out that my vim replacements to transform the Python code into Go code butchered all the URLs. ;-) The order of operations matters. I first replaced the equals with colons for the subtest struct fields and then wanted to transform the RFC 3339 timestamp strings to time.Date(ā¦) calls. So, I replaced the colons in the time with commas and spaces. Hence, my URLs then also all read https, //example.com/twtxt.txt.
But that was it. All test green. \o/
And regarding those broken URLs: I once speculated that these bots operate on an old dataset, because I thought that my redirect rules actually were broken once and produced loops. But a) I cannot reproduce this today, and b) I cannot find anything related to that in my Git history, either. But itās hard to tell, because I switched operating systems and webservers since then ā¦
But the thing is that Iām seeing new URLs constructed in this pattern. So this canāt just be an old crawling dataset.
I am now wondering if those broken URLs are bot bugs as well.
They look like this (zalgo is a new project):
https://www.uninformativ.de/projects/slinp/zalgo/scksums/bevelbar/
When you request that URL, you get redirected to /git/:
$ curl -sI https://www.uninformativ.de/projects/slinp/zalgo/scksums/bevelbar/
HTTP/1.0 301 Moved Permanently
Date: Sat, 22 Nov 2025 06:13:51 GMT
Server: OpenBSD httpd
Connection: close
Content-Type: text/html
Content-Length: 510
Location: /git/
And on /git/, there are links to my repos. So if a broken client requests https://www.uninformativ.de/projects/slinp/zalgo/scksums/bevelbar/, then sees a bunch of links and simply appends them, youāll end up with an infinite loop.
Is that whatās going on here or are my redirects actually still broken ⦠?
@prologic@twtxt.net I couldnāt have phrased it any better than @bender@twtxt.net. :-)
Twice or three times the money as before sounds a bit suspicious to me. Of course, I could be wrong, but I always was under the impression, that your last jobs werenāt all that badly salaried. If the new offer is really paid this highly, it might be a shit job. For me, money isnāt everything, Iād rather opt for a lower income where the job is fun than hating to go to work every day. But if the new job ticks all boxes, go for it. :-)
Also: Consult your pillow, donāt rush it.
@bender@twtxt.net Thatās actually kind of what I was going for, just with a stylized ātā and some blue/purple/red shades š¤£
@prologic@twtxt.net Hm, same startup delay. (Go is not an option for me anyway.)
Itās hard to tell why all this is so slow. Maybe in this particular case it has something to do with fonts: strace shows the program loading the fontconfig configs several times, and that takes up a bulk of the startup time. š¤ (Qt6 or Java donāt do that, but theyāre still slow to start up ā for other reasons, apparently.)
To be fair, itās ājustā the initial program startup (with warm I/O caches). Once itās running, itās fine. All toolkits Iāve tried are. But I donāt want to accept such delays, not in the year 2025. š Imagine every terminal window needing half a second to appear on the screen ⦠nah, man.
@prologic@twtxt.net we are not going to get far by blaming the other side. š š
I wound up running 2 out of 3 of the one-shots, both Halloween games based on Ravenloft / Curse of Strahd, and both rousing successes (for the players, not so much for Strahd).
Since Iām on something of a gaming kick, I think Iām going to try and finish plotting out the rest of the fae adventure Iām running for my kids, while also (hopefully) finishing my super secret astral gaming project.
Can I do it? Stay tuned and find out!
Car Size
ā Read more