As an enjoyer of delightfully bad graphic design, found on most Czech village center cork boards, I’m sad to see the stolen clipart and badly cropped watermarked stock images, gradually replaced with AI slop.
This is far from a serious rant, but generating images of my kind being telepathically hit with sharp rocks, surely gives me a right to complain.

So far these seem the most prominent slop categories, seem to be…
Architecture slop:
- find a sketch of what an old building looked like

- generate an AI version, without correcting any of the perspective errors - this one is diagonally levitating

- generate a recreation of the buildings demise - after going through the AI, for the second time, it is now a completely different building

Moralizing slop:


History slop:

Disclaimer: Can’t guarantee that I’m fully awake and I’m being trained at work not to use my brain anymore, so maybe this is complete bullshit. 😪🧟♀️
It says here that SQLite uses signed integers:
https://sqlite.org/datatype3.html
In pure bits, 1 << 63 would be 0x8000000000000000, but as a signed value, it gets interpreted as -9223372036854775808. Subtracting 1 yields -9223372036854775809 – but that doesn’t fit in 64 bits anymore. It’s possible that SQLite doesn’t want to wrap around but instead saturates? Haven’t checked. 🤔
With 62 bits, there is enough room.
With 1 << 64, I have no idea how SQLite wants to handle this, because this should immediately trigger a warning, because it doesn’t fit right away. Maybe it gets truncated to 0?
sqlite> select printf('0x%x', 2 * (1 << 64));
╭──────────────────────╮
│ printf('0x%x', 2 ... │
╞══════════════════════╡
│ 0x0 │
╰──────────────────────╯
sqlite> select printf('0x%x', 0 - 1);
╭──────────────────────╮
│ printf('0x%x', 0 ... │
╞══════════════════════╡
│ 0xffffffffffffffff │
╰──────────────────────╯
sqlite> select printf('0x%x', 0 - 2);
╭──────────────────────╮
│ printf('0x%x', 0 ... │
╞══════════════════════╡
│ 0xfffffffffffffffe │
╰──────────────────────╯
Eehhh, what the hell is going on here!?
SELECT
printf("0x%x", (1 << 63) - 2),
printf("0x%x", (1 << 63) - 1),
printf("0x%x", 1 << 63 ),
printf("0x%x", (1 << 63) + 1),
printf("0x%x", (1 << 63) + 2)
SQLite yields:
0x8000000000000000 (instead of 0x7ffffffffffffffe)
0x8000000000000000 (instead of 0x7fffffffffffffff)
0x8000000000000000 (correct)
0x8000000000000001 (correct)
0x8000000000000002 (correct)
Huh!? O_o Am I stupid? What am I missing here? Or is this actually a bug? :-?
With 62 bits, everything is spot on:
0x3ffffffffffffffe
0x3fffffffffffffff
0x4000000000000000
0x4000000000000001
0x4000000000000002
And 64 bits rather unsurprisingly also yield:
0xfffffffffffffffe
0xffffffffffffffff
0x0
0x1
0x2
I went 1 for 2 at Magic this week… Temmet made a good showing the first game before being overwhelmed by an infinite number of Wylls (aka Fred Durst, on account of all his “rollin’, rollin’, rollin’!”). As a result, I unleashed Chatterfang on the group for the second game, and he lead his squirrel army to victory once again. Good times!
@lyse@lyse.isobeef.org For reasons I can’t fully explain, we have a bunch of courses in the area, most in public parks (they integrate nicely since they can be built with the existing landscape, only adding some yellow baskets, concrete starting pads, and maybe signs).
In my experience, the main difference between a disc golfer and a frisbee thrower is that the disc golfer will often have a bag full of different shapes of discs (including drivers of varying ranges and/or putters). Even in my small bag, I’ve got some long range drivers (a Beast, a Cheetah, a Valkyrie, and a Wraith), my aforementioned MRV (Mid-Range Vector), an ultralight Aero (which feels similar to a “standard” frisbee), and 2 “rubber” putters (softer plastic, less “bouncy”).
Went 2/3 at Magic today: Prosper dominated game 1, Ash and his Knights came within a single planar die roll of winning game 2, and then Atraxa came up with the win in a fairly tight game 3. All in all, not a bad afternoon of Magic.
v2 branch and @doesnm.p.psf.lt has been incredibly helpful so far. Be great ot have a few more folks to join us, some of the v2 highlights include:
@bender@twtxt.net Here is a properly formatted version of your message:
Not yet — but that’s probably a good idea.
Instructions:
- Clone the repository
git clone https://git.mills.io/saltyim/saltyim.git
cd saltyim
- Check out the
v2branch
git checkout v2
- Build and install the CLI/TUI
make DESTDIR=$HOME/bin install
After installation, run:
salty-chat
I’ve got sore muscles. The sticky snow couldn’t be pushed, it had to be laborously cleared shovel by shovel. :-D
In my lunch break, I went on a short stroll. Oh boy, walking through deep damp snow is exhausting! There were sections with easily 30 centimeters and more. Some big wind drifts had piled up. Despite melting off quickly in the 4°C, especially turning the trees brown again, the white landscape still looks so nice. I’m glad these road marking sticks finally came in handy for the snow plow guys. :-) The black and orange stripes are 30 cm high.
https://lyse.isobeef.org/waldspaziergang-2026-01-26/
That’s probably it. There’s no significant snowfall announced for the rest of the week and temperatures are supposed to stay in the 2-4°C range by day.
@movq@www.uninformativ.de I was also extremely surprised and couldn’t believe it myself. But around the hair were definitely two, three millimeters of ice with a bunch of snow on top. I couldn’t simply brush it off, the hair were all frozen together. Back in the house, it took maybe three minutes to melt the solidified white stuff and free up and disconnect the individual hair. Crazy.
Yeah, 0°C in town, maybe -2°C on the summit. It definitely didn’t feel all the cold, but I came prepared with a few layers of cloth.
Wow, as I anticipated, this is waaay out of my capabilities to really understand it. But I’m quite happy to just have spotted a mistake in an explanatory comment in section 4.5.2 “The icode Array”. Of course, it should be /e + tc + /i + ni + t\0. Let’s hope that my e-mail with the patch actually makes it into Briam’s inbox. I fear GMail just hides it in the spam folder.
I’m trying to implement configurable key bindings in tt. Boy, is parsing the key names into tcell.EventKeys a horrible thing. This type consists of three information:
- maybe a predefined compound key sequence, like Ctrl+A
- maybe some modifiers, such as Shift, Ctrl, etc.
- maybe a rune if neither modifiers are present nor a predefined compound key exists
It’s hardcoded usage results in code like this:
func (t *TreeView[T]) InputHandler() func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
return t.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
switch event.Key() {
case tcell.KeyUp:
t.moveUp()
case tcell.KeyDown:
t.moveDown()
case tcell.KeyHome:
t.moveTop()
case tcell.KeyEnd:
t.moveBottom()
case tcell.KeyCtrlE:
t.moveScrollOffsetDown()
case tcell.KeyCtrlY:
t.moveScrollOffsetUp()
case tcell.KeyTab, tcell.KeyBacktab:
if t.finished != nil {
t.finished(event.Key())
}
case tcell.KeyRune:
if event.Modifiers() == tcell.ModNone {
switch event.Rune() {
case 'k':
t.moveUp()
case 'j':
t.moveDown()
case 'g':
t.moveTop()
case 'G':
t.moveBottom()
}
}
}
})
}
This data structure is just awful to handle and especially initialize in my opinion. Some compound tcell.Keys are mapped to human-readable names in tcell.KeyNames. However, these names always use - to join modifiers, e.g. resulting in Ctrl-A, whereas tcell.EventKey.Name() produces +-delimited strings, e.g. Ctrl+A. Gnaarf, why this asymmetry!? O_o
I just checked k9s and they’re extending tcell.KeyNames with their own tcell.Key definitions like crazy: https://github.com/derailed/k9s/blob/master/internal/ui/key.go Then, they convert an original tcell.EventKey to tcell.Key: https://github.com/derailed/k9s/blob/b53f3091ca2d9ab963913b0d5e59376aea3f3e51/internal/ui/app.go#L287 This must be used when actually handling keyboard input: https://github.com/derailed/k9s/blob/e55083ba271eed6fc4014674890f70c5ed6c70e0/internal/ui/tree.go#L101
This seems to be much nicer to use. However, I fear this will break eventually. And it’s more fragile in general, because it’s rather easy to forget the conversion or one can get confused whether a certain key at hand is now an original tcell.Key coming from the library or an “extended” one.
I will see if I can find some other programs that provide configurable tcell key bindings.
@eldersnake@we.loveprivacy.club
Steps to world domination:
- “Invent” “AI” (by using other people’s data).
- Get people hyped about it and ideally hooked on it.
- Only provide it as a cloud service. But hey, if you want to, you can run it locally!
- Buy all hardware available on the market, so that nobody but you can build more systems.
- All PCs of consumers and competitors are too weak now and can’t be upgraded anymore.
- Everybody depends on your cloud service! Win!
All of that is possible because corporations don’t have a “conscience” in capitalism. Nobody forces the RAM manufacturers to sell all their stuff to just one or two buyers, but since the only goal of that manufacturer is to make money, they do it.
@movq@www.uninformativ.de Well, just a very limited subset thereof:
- inline and multiline code blocks using single/double/triple backticks (but no code blocks with just indentation)
- markdown links using using
[text](url)
- markdown media links using

And that’s it. No bold, italics, lists, quotes, headlines, etc.
Just like mentions, plain URLs, markdown links and markdown media URLs are highlighted and available in the URLs View. They’re also colored differently, similarly to code segments.
I definitely should write some documentation and provide screenshots.
@movq@www.uninformativ.de Yeah, I see. Just crudely checked on my computer, with around 0.013 seconds, Python 2.7 seems a tad faster than Python 3.14’s 0.023 seconds in this little program.
The lazy imports sound not too bad, but I just skimmed over them. There are surprisingly many exceptions, but yeah, no way around them. :-)
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.
Whoo! I fixed one of the hardest bugs in mu (µ) I think I’ve had to figure out. Took me several days in fact to figure it out. The basic problem was, println(1, 2) was bring printed as 1 2 in the bytecode VM and 1 nil when natively compiled to machine code on macOS. In the end it turned out the machine code being generated / emitted meant that the list pointers for the rest... of the variadic arguments was being slot into a register that was being clobbered by the mu_retain and mu_release calls and effectively getting freed up on first use by the RC (reference counting) garbage collector 🤦♂️
My little toy operating system from last year runs in 16-bit Real Mode (like DOS). Since I’ve recently figured out how to switch to 64-bit Long Mode right after BIOS boot, I now have a little program that performs this switch on my toy OS. It will load and run any x86-64 program, assuming it’s freestanding, a flat binary, and small enough (< 128 KiB code, only uses the first 2 MiB of memory).
Here I’m running a little C program (compiled using normal GCC, no Watcom trickery):
https://movq.de/v/b27ced6dcb/los86%2D64.mp4
https://movq.de/v/b27ced6dcb/c.png
Next steps could include:
- Use Rust instead of C for that 64-bit program?
- Provide interrupt service routines. (At the moment, it just keeps interrupts disabled.)
@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.
I rewrote all my solutions in Rust (except for day 10 part 2) and these are the runtimes on my i7-3770 from 2013 (this measures CLOCK_PROCESS_CPUTIME_ID, not wallclock):
day01/1 [ 00.000501311] Result: 1066
day01/2 [ 00.000400298] Result: 6223
day02/1 [ 00.000358848] Result: 12586854255
day02/2 [ 00.000750711] Result: 17298174201
day03/1 [ 00.000106537] Result: 17405
day03/2 [ 00.000404632] Result: 171990312704598
day04/1 [ 00.000257517] Result: 1626
day04/2 [ 00.007495342] Result: 9173
day05/1 [ 00.000237212] Result: 505
day05/2 [ 00.000142731] Result: 344423158480189
day06/1 [ 00.000229629] Result: 4076006202939
day06/2 [ 00.000279552] Result: 7903168391557
day07/1 [ 00.000204422] Result: 1622
day07/2 [ 00.000283816] Result: 10357305916520
day08/1 [ 00.029427421] Result: 84968
day08/2 [ 00.028089859] Result: 8663467782
day09/1 [ 00.000310304] Result: 4764078684
day09/2 [ 00.015512554] Result: 1652344888
day10/1 [ 00.000796663] Result: 375
day10/2 [ --.---------] Result: 15377 (Z3)
day11/1 [ 00.000416804] Result: 753
day11/2 [ 00.000660528] Result: 450854305019580
day12/1 [ 00.000336081] Result: 577
day12/2 [ 00.000000695] Result: no part 2
A little under 90 ms total.
On my Samsung NC10 netbook from 2011 with its Intel Atom N455 at 1.6 GHz:
day01/1 [ 00.003771326] Result: 1066
day01/2 [ 00.003267317] Result: 6223
day02/1 [ 00.003902698] Result: 12586854255
day02/2 [ 00.006659479] Result: 17298174201
day03/1 [ 00.000747544] Result: 17405
day03/2 [ 00.002737587] Result: 171990312704598
day04/1 [ 00.001263892] Result: 1626
day04/2 [ 00.044985301] Result: 9173
day05/1 [ 00.001696761] Result: 505
day05/2 [ 00.000978962] Result: 344423158480189
day06/1 [ 00.001387660] Result: 4076006202939
day06/2 [ 00.001734248] Result: 7903168391557
day07/1 [ 00.001295528] Result: 1622
day07/2 [ 00.001809659] Result: 10357305916520
day08/1 [ 00.277251443] Result: 84968
day08/2 [ 00.284359332] Result: 8663467782
day09/1 [ 00.003152407] Result: 4764078684
day09/2 [ 00.071123459] Result: 1652344888
day10/1 [ 00.005279527] Result: 375
day10/2 [ --.---------] Result: 15377 (Z3)
day11/1 [ 00.003273342] Result: 753
day11/2 [ 00.005139719] Result: 450854305019580
day12/1 [ 00.002857552] Result: 577
day12/2 [ 00.000004421] Result: no part 2
A little over 700 ms total.
I like this. You get performance that’s more or less in the ballpark of C, but without the footguns.
@movq@www.uninformativ.de I shrank Day 9 Part 2 from “cover the whole map” to “only track the interesting lines.” By compressing coordinates to just the unique x/y breakpoints, the grid got tiny. I still flood-fill and do the corner-pair checks, but now on that compact grid with weighted prefix sums for instant rectangle checks. Result: far less RAM, way less CPU, same correct answer.
Day 7 was pretty tough, I initially ended up implementing an exponential in both time and memory solution that I killed because it was eating all the resources on my Mac Studio, and this poor little machine only has 32GB of memory (I stopped it at 118GB of memory, swapping badly!), This is what I ended up doing before/after:
- Before: Time O(2^k · L), memory O(2^k), where k is the number of splitters along a reachable path and L is path length. Exponential in k.
- After: Time O(R·C) (or O(R·C + s) with s split events), memory O©, where R = rows, C = columns. Polynomial/linear in grid size.
I just completed “Gift Shop” - Day 2 - Advent of Code 2025 #AdventOfCode https://adventofcode.com/2025/day/2 – But again, I’m solving this in my own language mu that I had to build first 🤣
Alright, Advent of Code is over:
https://www.uninformativ.de/blog/postings/2025-12-12/0/POSTING-en.html
It’s been quite the time sink, especially with the DOS games on top, but it was fun. 🥳
In case you’re wondering: All puzzles (except for part 2 of day 10) were doable in Python 1 on SuSE Linux 6.4 and ran in a finite time on the Pentium 133. Puzzle 10/2 might have been doable as well if I had better education. 🤣
Day 2 was pretty tough on my old hardware. Part 1 originally took 16 minutes, then I got it down to 9 seconds – only to realize later that my solution abused some properties of my particular input. A correct solution will probably take about 30 seconds. 🫤
Part 2 took 29 minutes this morning. I wrote an optimized version but haven’t tested it yet. I hope it’ll be under a minute.
Python 1 feels really slow, even compared to Java 1. And these first puzzles weren’t even computationally intensive. We’ll see how far I’ll make it …
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. 🎄
@lyse@lyse.isobeef.org Damn. That was stupid of me. I should have posted examples using 2026-03-01 as cutoff date. 😂
In my actual test suite, everything uses 2027-01-01 and then I have this, hoping that that’s good enough. 🥴
def test_rollover():
d = jenny.HASHV2_CUTOFF_DATE
assert len(jenny.make_twt_hash(URL, d - timedelta(days=7), TEXT)) == 7
assert len(jenny.make_twt_hash(URL, d - timedelta(seconds=3), TEXT)) == 7
assert len(jenny.make_twt_hash(URL, d - timedelta(seconds=2), TEXT)) == 7
assert len(jenny.make_twt_hash(URL, d - timedelta(seconds=1), TEXT)) == 7
assert len(jenny.make_twt_hash(URL, d, TEXT)) == 12
assert len(jenny.make_twt_hash(URL, d + timedelta(seconds=1), TEXT)) == 12
assert len(jenny.make_twt_hash(URL, d + timedelta(seconds=2), TEXT)) == 12
assert len(jenny.make_twt_hash(URL, d + timedelta(seconds=3), TEXT)) == 12
assert len(jenny.make_twt_hash(URL, d + timedelta(days=7), TEXT)) == 12
(In other words, I don’t care as long as it’s before 2027-01-01. 😏😅)
@aelaraji@aelaraji.com Thanks for the account! I figured out one thing at least so far, my WAF was blocking some of the AP requests. Fixed that. Anyway, holiday time 🤣 Back in ~2 weeks.
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.
@lyse@lyse.isobeef.org Probably wouldn’t help, since almost every request comes from a different IP address. These are the hits on those weird /projects URLs since Sunday:
1 IP has 5 hits
1 IP has 4 hits
13 IPs have 3 hits
280 IPs have 2 hits
25543 IPs have 1 hit
The total number of hits has decreased now. Maybe the botnet has moved on …
@lyse@lyse.isobeef.org @bender@twtxt.net Pfft, they want folks to relocate to Sydney. Fuck that 🤣 Sydney is a bit like San Francisco, I’m not actually sure which is worse. Fuck’n expensive as hell, the only palce you’d be able to afford to buy or rent is at least ~2hrs out of the city by public transport (i.e: train) and by that time you’ve just pissed your life down the toilet, because you’d be expected ot work a 9-10hr day + 2-3hrs of travel each way, buy the time you factor in having to wake up super early to get ready to travel in to work, you basically have zero time for anything else, let alone your ufamily,
Fuck that.
What do you do, when a recruiter throws you a PD or two and says the total compensation is ~2-3x what you’re on now?! 🤔
Testing 1 2 3
Testing 1 2 3
FTR, I see one (two) issues with PyQt6, sadly:
- The PyQt6 docs appear to be mostly auto-generated from the C++ docs. And they contain many errors or broken examples (due to the auto-conversion). I found this relatively unpleasent to work with.
- (Until Python finally gets rid of the Global Interpreter Lock properly, it’s not really suited for GUI programs anyway – in my opinion. You can’t offload anything to a second thread, because the whole program is still single-threaded. This would have made my fractal rendering program impossible, for example.)
Testing 1 2 3 @manton@twtxt.net
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!
For those curious, the new Twtxt <-> ActivityPub bridge I’m building (bidirectional) simply requires three things:
- You register your Twtxt feed to the bridge: https://bridge.twtxt.net
- You verify that you in fact own/control the feed by putting the verification code somewhere on/in your feed (doesn’t matter where or how)
- You proxy/forward requests for
/.well-known/webfingerto the Bridgebridge.twtxt.net.
I’m still testing through and ironing out bugs 🐛 Please be patient! 🙏
My goodness, a new level of stupidity.
The bots are now doing things like this:
GET http://uninformativ.de/projects/lariza/feednotify/datenstrahler/slinp/countty HTTP/1.1
- That URL does not exist.
- By including
http://uninformativ.dein that request, this instructs the webserver to do an HTTP proxy request. Of course, this isn’t allowed on my webserver (and shouldn’t by allowed on any normal webserver), resulting in HTTP 400. And even if it were, the target would be the exact same server, making a proxy request unnecessary.
And of course, it’s not just 50 hits like this or 100 or 1’000 or 10’000. No, it’s over 150’000 in the last 2 days. All from vastly different IP ranges of different cloud hosters.
This almost looks like a DDoS attack, but it’s just completely stupid. This feels more like some idiot vibe coded a crawler.
@movq@www.uninformativ.de Gemini liked your opinion very much. Here is how it countered:
1. The User Perspective (Untrustworthiness)The criticism of AI as untrustworthy is a problem of misapplication, not capability.
- AI as a Force Multiplier: AI should be treated as a high-speed drafting and brainstorming tool, not an authority. For experts, it offers an immense speed gain, shifting the work from slow manual creation to fast critical editing and verification.
- The Rise of AI Literacy: Users must develop a new skill—AI literacy—to critically evaluate and verify AI’s probabilistic output. This skill, along with improving citation features in AI tools, mitigates the “gaslighting” effect.
The fear of skill loss is based on a misunderstanding of how technology changes the nature of work; it’s skill evolution, not erosion.
- Shifting Focus to High-Level Skills: Just as the calculator shifted focus from manual math to complex problem-solving, AI shifts the focus from writing boilerplate code to architectural design and prompt engineering. It handles repetitive tasks, freeing humans for creative and complex challenges.
- Accessibility and Empowerment: AI serves as a powerful democratizing tool, offering personalized tutoring and automation to people who lack deep expertise. While dependency is a risk, this accessibility empowers a wider segment of the population previously limited by skill barriers.
The legal and technical flaws are issues of governance and ethical practice, not reasons to reject the core technology.
- Need for Better Bot Governance: Destructive scraping is a failure of ethical web behavior and can be solved with better bot identification, rate limits, and protocols (like enhanced
robots.txt). The solution is to demand digital citizenship from AI companies, not to stop AI development.
Won a bunch of games of Solitaire and then rearranged the cards for maximum negative points, to distract me from the horrors.
(Still ended up with >0 points on OS/2, because don’t ask me.)
https://www.uninformativ.de/desktop/2025%2D11%2D04%2D%2Dkatriawm%2Dsolitaire.png
There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of processing 2. Exactly-once delivery
@movq@www.uninformativ.de streamlining jenny.vim?
index adc0db9..cb54abc 100644
--- a/vim/ftdetect/jenny.vim
+++ b/vim/ftdetect/jenny.vim
@@ -1 +1,2 @@
au BufNewFile,BufRead jenny-posting.eml setl completefunc=jenny#CompleteMentions fo-=t wrap
+au BufRead,BufNewFile jenny-posting.eml normal $
@lyse@lyse.isobeef.org In my case it was a silver necklace, a hummingbird with a wing connected with the cold welding I mentioned using thin brass wires.
It made it in a goldsmithing class (I went to a private craftmanship high-school) so no phones allowed (no photos of it) and no “take home” of the works.
Here’s a rough sketch of it drawn by memory, the dots in the wing is where it connects to the body.

The technique is basically the same as i described, but the scale is much smaller, the whole piece was about 5-6 cm on the largest side.
The rivet was made by drilling a hole through the parts, than with a short and thicker drill you widen the hole on the surface to let the rivet settle flatter on the piece, then with a rubber hammer you hit it to flatten the head until it’s snug on the hole, lock them together by doing the same on the other side.
Note that widening the hole with a thicker drill head won’t make a difference with bigger holes, mine had holes of about 1-2 mm of diameter maximum.
Here’s a sketch of what is going on for clarity.

I experimented with a 2.4x7mm aluminium rivet I had on hand. As expected, it was quite a bit long. Using my pliers wrench, I was able to crush it down by quite some bit. I should have taken a photo right after the hand riveter for comparison. Now, it’s much smoother and the chance of cutting my hand open is reduced by quite a bit. But breaking the burr with a few file strokes is still necessary. I should get 2.4x4mm rivets and try with them. I reckon they would be more suited for my 0.5mm sheet metal.
With the pliers wrench again, I was able to also crush down the chopped off 3mm copper nail and form a second head. That was surprisingly easy. Now, I need to figure out how to efficiently make a head on the remaining copper nail shaft, so that I can use this again.
Both are rock solid, there’s absolutely no movement at all between the two sheet metal cutoffs.
Okay, they are also offering 2.8x25mm copper nails. Which I actually do have a single one here. :-)
My hardware collection also includes a few brass-like looking screws that I could repurpose into rivets. But I reckon I have to upgrade my burner first. I’m not a metal worker by any means, so I could be totally wrong, but I imagine that some heat is necessary to loosen the work-hardening effect when beating on them. I will do some experiments on Saturday and report back.
@itsericwoodward@itsericwoodward.com No worries, all good, mate! We all have to start somewhere. Other software requests my feed several orders of magnitude more often.
I can confirm, the User-Agent header appears to be fixed. \o/
Two other things I noticed, though:
There’s now an
OPTIONSrequest for my feed coming from something that claims to be Firefox, pointing to your feed URL in the query. No clue what this is about. In any case, it’s rejected with a405 Method Not Allowed.Not that these few requests bother me at all, but you might wanna implement caching next with either the
If-Modified-SinceorIf-None-Matchrequest headers. This way, if the feed hasn’t changed, the web server can reply with a304 Not Modifiedand no body at all, saving unnecessary traffic. But again, this is really not an issue for me at all. I just wanted to make sure you’re aware of it, that’s all. It might be even already on your agenda. Or you might decide to never do anything about it, which is also fine for me. :-)
Please don’t hate me today; I’m a bit grumpy and have too many reasons to be upset:
- 2 counts of pushing and trying to get the simplest things done at work (that for some reason are made more difficult than they should be)
- This whole Chat Control bullshit
- And some other person things going on that have been ongoing for 72 days and counting 🤬
Each origin feed numbers new threads
(tno:N). Replies carry both (tno:N) and (ofeed:<origin-url>). Thread identity = (ofeed, tno).
@prologic@twtxt.net I think a counter in the client is not a good choice given the decentralized nature of twtxt, especially if someone use multiple cients together.
After thinking about it for a while I got to two solutions:
Proposal 1: Thread syntax (using subject)
Each post have an implicit and an optional explicit root reference:
Implicit (no action needed, all data required are already there)
- URL + timestamp
- URL + timestamp
Explicit (subject required)
- Identity (client generated)
- External reference
- Random value
- Identity (client generated)
We then add include a “root” subject in each post for generating explicit theads:
1. `[ROOT_ID] (REPLY_ID)`: simpler with no need of prefixes
2. `(root:ROOT_ID) (reply:REPLY_ID)`: more complex but could allow expansions
- `(rt:ROOT_ID) (re:REPLY_ID)`: same but with a compact version
- `($ROOT_ID) (>REPLY_ID)`: same but with a single characters
Each post can have both references, like the current hash approach the reference can be treated as a simple string and don’t have a real meaning.
Using a custom reference this way allows a client to decide how to generate them:
- Identity: can be a content hash or signature or anything else, without enforcing how it is generated we can upgrade the algorithm/length freely
- External references: can be provided from another system (Eg.
7e073bd345, yarnsocial/yarn latest commit)
- Random value: like a UUID (Eg.
9a0c34ed-d11e-447e-9257-0a0f57ef6e07)
Proposal 2: Threaded mentions (featuring zvava)
Inspired by @zvava@twtxt.net’s solution it could be simplified into: #<nick url#timestamp> or #<url#timestamp>
It can be shown like a mentions or hidden like a subject.
If we’re using thinking of using a counter in the client, I think there’s no point in avoiding the timestamp anymore.
@bender@twtxt.net Thanks for asking!
So, I’ve been working on 2 main twtxt-related projects.
The first is small Node / express application that serves up a twtxt file while allowing its owner to add twts to it (or edit it outright), and I’ve been testing it on my site since the night I made that post. It’s still very much an MVP, and I’ve been intermittently adding features, improving security, and streamlining the code, with an eye to release it after I get an MVP done of project #2 (the reader).
But that’s where I’ve been struggling. The idea seems simple enough - another Node / express app (this one with a Vite-powered front-end) that reads a public twtxt file, parses the “follow” list, grabs (and parses) those twtxt files, and then creates a river of twts out of the result. The pieces work fine in seclusion (and with dummy data), but I keep running into weird issues when reading real-live twtxt files, so some twts come through, while others get lost in the ether. I’ll figure it out eventually, but for now, I’ve been spending far more time than I anticipated just trying to get it to work end-to-end.
On top of it, the 2 projects wound up turning into 4 (so far), as I’ve been spinning out little libraries to use across both apps (like https://jsr.io/@itsericwoodward/fluent-dom-esm, and a forthcoming twtxt helper library).
In the end, I’m hoping to have project 1 (the editor) into beta by the end of October, and project 2 (the reader) into beta sometime after that, but we’ll see.
I hope this has satisfied your curiosity, but if you’d like to know more, please reach out!
@bender@twtxt.net Thanks for asking!
So, I’ve been working on 2 main twtxt-related projects.
The first is small Node / express application that serves up a twtxt file while allowing its owner to add twts to it (or edit it outright), and I’ve been testing it on my site since the night I made that post. It’s still very much an MVP, and I’ve been intermittently adding features, improving security, and streamlining the code, with an eye to release it after I get an MVP done of project #2 (the reader).
But that’s where I’ve been struggling. The idea seems simple enough - another Node / express app (this one with a Vite-powered front-end) that reads a public twtxt file, parses the “follow” list, grabs (and parses) those twtxt files, and then creates a river of twts out of the result. The pieces work fine in seclusion (and with dummy data), but I keep running into weird issues when reading real-live twtxt files, so some twts come through, while others get lost in the ether. I’ll figure it out eventually, but for now, I’ve been spending far more time than I anticipated just trying to get it to work end-to-end.
On top of it, the 2 projects wound up turning into 4 (so far), as I’ve been spinning out little libraries to use across both apps (like https://jsr.io/@itsericwoodward/fluent-dom-esm, and a forthcoming twtxt helper library).
In the end, I’m hoping to have project 1 (the editor) into beta by the end of October, and project 2 (the reader) into beta sometime after that, but we’ll see.
I hope this has satisfied your curiosity, but if you’d like to know more, please reach out!