Please enable JS and disable any ad blocker
10 interesting stories served every morning and every evening.
10 interesting stories served every morning and every evening.
Please enable JS and disable any ad blocker
The most powerful rocket in history just roared off its launch pad in a spectacular show of power and technology.
SpaceX launched the newest version of its giant Starship rocket Friday (May 22), from a recently completed second pad at its Starbase manufacturing and test facility in South Texas. Liftoff occurred at 6:30 p.m. EDT (2230 GMT), sending the massive 408-foot-tall (124-meter) vehicle skyward on its 12th suborbital test flight.
It was the first Starship mission since October 2025, and the first-ever flight of Starship Version 3 (V3), a next-generation build of the rocket that features a complete design overhaul meant to evolve the vehicle toward operational missions. And today’s suborbital Flight 12 was a significant step toward that ambitious goal, even if it was a day later than planned after a glitched thwarted a first launch try on Thursday.
“Congratulations SpaceX team on an epic first Starship V3 launch & landing!,” SpaceX CEO Elon Musk wrote on X after the launch. “You scored a goal for humanity.”
Image
1
of
3
There were some hiccups.
During liftoff, one of the 33 first-stage Raptor engines on Super Heavy shut down, and the booster missed a critical “boost back” manuever to control its return to Earth. Starship’s Ship 39 upper stage also lost one of its six main engines during ascent, but managed to reach space on the remaining five.
“I wouldn’t call it nominal orbital insertion, but we’re in on a trajectory that we had analyzed, and it’s within bounds,” SpaceX spokesperson Dan Huot said in live commentary. “So, teams continuing to work through it with that engine out there, working some through some steps on the engines.”
Starship consists of a first-stage booster called Super Heavy and an upper stage known as Starship, or simply Ship. The first notable event after the rocket cleared the tower this evening occurred about 2 minutes and 20 seconds into flight, when Super Heavy initiated “hot staging” and separation from Ship. (It’s known as hot staging because Ship begins firing its engines before separating from Super Heavy.)
Unlike its V2 predecessor, which featured an interstage ring that fell away at separation, Starship V3 is built with similar hardware secured to the top of the booster, like a fence around the fuel tank’s dome to give some breathing room to the upper stage engines’ ignition and initial thrust away from the booster.
After stage separation, Super Heavy reoriented and attempted to perform a one-minute boostback burn toward Starbase. However, something went wrong and the burn didn’t go as planned, Huot said.
SpaceX has performed booster recoveries at Starbase on previous Starship missions, catching the rocket’s first stage using mechanical “chopstick” arms attached to the site’s launch towers. On Flight 12, however, the company planed to return Super Heavy a soft splashdown in the Gulf of Mexico rather than risk a recovery mishap that could damage the pad on the first flight of brand-new hardware.
Instead, the massive Super Heavy booster plummeted back to Earth and crashed into the Gulf, beaming live views of its fall from space until the screen went black.
“The booster didn’t complete its full boost back,” Huot said just after lifotff. “Its mission ended a little bit early, but landed in the clear area that we had set in advance.”
SpaceX included 22 payloads for Ship to deploy during its suborbital jaunt today — 20 dummy versions of the company’s Starlink broadband satellites and two actual Starlink spacecraft equipped with imaging sensors.
The payloads were deployed as planned over a 10-minute span, beginning roughly 17 minutes after launch, via Ship’s “PEZ dispenser”-like door. The two modified Starlink satellites were tasked with scanning Starship’s heat shield tiles, in a test meant to assess the ability to inspect them for possible damage prior to reentry.
Shortly after the final two Starlink simulators deployed (the ones with cameras that SpaceX nicknamed “Dodger Dogs” after the famed hotdogs at Dodger Stadium), SpaceX broadcast the spectactular video they captured as they flew away from Starship.
“That is a Starship in space,” Huot said.
Image
1
of
2
SpaceX initially planned for the Ship 39 upper stage to perform an in-space relight of one of its six Raptor engines in orbit— an important demonstration to prove the spacecraft can reliably execute maneuvers, as mixing and managing cryogenic fuels and reigniting an engine in zero-g is necessary to alter Ship’s orbit, send it on to the moon or Mars, and bring it back to Earth for recovery and reuse. But because of the lost Raptor engine during launch, flight controllers skipped that test for Flight 12.
And so, the first Starship V3 spacecraft began its descent to Earth.
Ship began its reentry to Earth’s atmosphere about 50 minutes into the flight, falling as its belly became engulfed in a bright plasma. During its descent, Ship 39 performed a series of exercises designed to stress parts of the vehicle to their structural limit. It also executed a novel banking maneuver for its landing burn meant to mimic the trajectory and orientation needed for a launch tower catch on a return to Starbase.
Huge cheers rang out at SpaceX’s headquareters and Starbase facilities as the Ship 39 ignited two engines for a final landing burn. The manuever initially called for three engines, but that one shut down early at liftoff. After the landing, Starship toppled over into the ocean waters and exploded in a magnificent fireball (again, as planned) as SpaceX workers cheered.
Nothing Starship accomplished on Flight 12 was particularly groundbreaking for SpaceX; the mission goals and trajectories were broadly similar to those of the previous few test missions.
However, even successfully following a previously blazed trail was huge for Starship V3, given that it’s a brand-new vehicle with a variety of modifications and upgrades over its predecessors. And V3′s road to the launch pad was a bit rocky.
SpaceX ran into some issues during the testing of the new V3 build in November last year, resulting in the loss of the Super Heavy booster originally slated for the Flight 12 mission. Now, with more than half a year between Starship’s last two launches, SpaceX has some catching up to do.
NASA is relying on Starship as one of the crewed lunar landers for its Artemis program, which aims to eventually establish a permanent human presence on the moon. The space agency has also contracted Blue Moon, a Blue Origin spacecraft, to land Artemis astronauts on the moon, and has indicated a willingness to fly with whichever private lander is ready when it’s time for the missions to get off the ground.
The next of those missions is Artemis 3 — the follow-up to April’s Artemis 2, which flew four astronauts aboard NASA’s Orion spacecraft on a successful 10-day mission around the moon. NASA is targeting mid to late 2027 for Artemis 3, which will launch Orion to low Earth orbit (LEO) to rendezvous and dock with one or both of the private lunar landers, and late 2028 for the first lunar landing on Artemis 4.
As if to drive that fact home, NASA chief Jared Isaacman flew to Starbase to watch the launch personally.
“We’re looking forward to seeing this thing fly, because hopefully at some point in the not too distant future we’re gonna, we’re gonna join up in an earth orbit,” Isaacman said during the live comentary.
After the launch, Isaacman hailed the work of SpaceX’s Starship team.
“Congrats SpaceX team and Elon Musk on a hell of a V3 Starship launch,” Isaacman wrote on X. “One step closer to the Moon … one step closer to Mars.”
Congrats @SpaceX team and @elonmusk on a hell of a V3 Starship launch. One step closer to the Moon…one step closer to Mars 🇺🇸 pic.twitter.com/jjetQxnkiRMay 23, 2026
Congrats @SpaceX team and @elonmusk on a hell of a V3 Starship launch. One step closer to the Moon…one step closer to Mars 🇺🇸 pic.twitter.com/jjetQxnkiRMay 23, 2026
Starship has a number of boxes to check before NASA certifies the vehicle to fly astronauts, but V3 has been built with those goalposts in mind.
The new Starship V3 vehicle includes four passive connection ports on its back, or leeward, side (opposite the heat tiles on its belly), which are designed for docking and ship-to-ship fuel transfers.
In order to fly beyond LEO, Starship requires the assistance of additional Ships to meet up in orbit to top off its fuel tanks. This is especially important for its use as the Artemis moon lander; experts have estimated that each lunar Starship mission could require a dozen or more refueling launches to adequately supply enough propellant to get to the moon, land and launch back to lunar orbit.
Ship has yet to demonstrate in-space refueling, or even a launch that fully reaches Earth orbit. And there are other boxes it needs to tick as well.
For example, NASA is requiring both Starship and Blue Moon to demonstrate uncrewed lunar landings before they fly astronauts down to the lunar surface, putting SpaceX and Blue Origin on a short timeline to ready vehicles for the planned Artemis 4 landing in 2028.
Starship’s launch today helps put it back on track toward meeting that goal, but SpaceX will have to pick up its launch cadence significantly. Just over a year ago, in March 2025, SpaceX founder and CEO Elon Musk posted on X that he expected to be launching V3 at a “rate of once a week in [about] 12 months.”
While that cadence still seems a long way off at Starship’s current state of development, the success of Flight 12 bodes well for the near future. And hopefully the near future features another Starship launch — a giant rocket getting off the ground in a matter of weeks, versus the seven months that separated today’s mission from the previous test flight.
Josh Dinner is Space.com’s Spaceflight Staff Writer. He is a writer and photographer with a passion for science and space exploration, and has been working the space beat since 2016. Josh has covered the evolution of NASA’s commercial spaceflight partnerships and crewed missions from the Space Coast, NASA science missions and more. He also enjoys building 1:144-scale model rockets and spacecraft. Find some of Josh’s launch photography on Instagram, and follow him on X, where he mostly posts in haiku.
Introduction
The <dl>, or description list, element is underrated.
It’s used to represent a list of name–value pairs. This is a common UI pattern that, at the same time, is incredibly versatile. For instance, you’ve probably seen these layouts out in the wild…
Each of these examples shows a list (or lists!) of name–value pairs. You might have also seen lists of name–value pairs to describe lodging amenities, or to list out individual charges in your monthly rent, or in glossaries of technical terms. Each of these is a candidate to be represented with the <dl> element.
So what does that look like?
The Anatomy of a Description List
I’ve been saying “<dl>,” when really, I’m talking about three separate elements: <dl>, <dt>, and <dd>.
We start with our <dl>. This is the description list,note 1 akin to using a <ul> for an unordered list or an <ol> for an ordered list.
<dl>
</dl>
Fancy.
Next up, we want to add a name–value pair. We’ll use a <dt>, short for description term, for the name, and we’ll use a <dd>, short for description detail, for the value.note 2
<dl> <dt>Title</dt> <dd>Designing with Web Standards</dd> </dl>
To add another name–value pair to our list, we add another <dt> and <dd>:
<dl> <dt>Title</dt> <dd>Designing with Web Standards</dd> <dt>Publisher</dt> <dd>New Riders Pub; 3rd edition (October 19, 2009)</dd> </dl>
But wait — what if I have a term that has multiple values? For instance, what if this book has multiple authors?
That’s fine! One <dt> can have multiple <dd>s:
<dl> <dt>Title</dt> <dd>Designing with Web Standards</dd> <dt>Author</dt> <dd>Jeffrey Zeldman</dd> <dd>Ethan Marcotte</dd> <dt>Publisher</dt> <dd>New Riders Pub; 3rd edition (October 19, 2009)</dd> </dl>
There’s one last piece of the description list anatomy to look at for most basic use cases: what if I want to wrap a <dt> and its <dd>(s) for styling reasons?
In this case, the specs allow you to wrap a <dt> and its <dd>(s) in a <div>:
<dl>
<div> <dt>Title</dt> <dd>Designing with Web Standards</dd> </div>
<div> <dt>Author</dt> <dd>Jeffrey Zeldman</dd> <dd>Ethan Marcotte</dd> </div>
<div> <dt>Publisher</dt> <dd>New Riders Pub; 3rd edition (October 19, 2009)</dd> </div>
</dl>
A wrapper <div> like this is the only element that can wrap those <dt>/<dd> groups.
And that’s it! That’s the anatomy of the description list, HTML’s semantic way to mark up a list of name–value groups!
Why Do We Need Semantics For This Anyways?
Before we learned about the <dl>, <dt>, and <dd> elements, my team used to use nested <div>s for this pattern all the time. It looked a lot like:
<div class=“book-details”> <div class=“book-details–item”> <div class=“book-details–label”> Title </div> <div class=“book-details–value”> Designing with Web Standards </div> </div> <div class=“book-details–item”> <div class=“book-details–label”> Author </div> <div class=“book-details–value”> Jeffrey Zeldman </div> <div class=“book-details–value”> Ethan Marcotte </div> </div> <div class=“book-details–item”> <div class=“book-details–label”> Publisher </div> <div class=“book-details–value”> New Riders Pub; 3rd edition (October 19, 2009) </div> </div> </div>
This has all the information about the book, right? Why do we need semantics for a list of name–value groups in the first place if something like a series of nested <div>s could get the job done?
When determining whether a semantic element might be appropriate for a given pattern, I find it helpful to ask, “What benefits — even theoretical — could we get if computers could recognize this pattern?” In this case, what lift could we get if browsers could somehow recognize a list of name–value groups?
Answers to that question will be varied. I tend to spend a lot of time advocating for web accessibility, so my first thought tends to be how screenreaders could interpret the pattern. Off the top of my head, I can think of a couple of benefits screenreader users could get from their screenreaders recognizing this pattern:
The screenreader could tell the user how many name–value groups are in the list.
The screenreader could tell the user how far into the list they are.
The screenreader could treat the list as one block that the user could skip over if they’re uninterested in it.
All of these could make the list more usable than a series of nested <div>s, which would treat each name and value in the list as nothing more than a standalone text node.
If you can come up with a couple of even theoretical lifts from the user’s device recognizing a pattern, then there’s a good chance that the pattern is a strong candidate for having some associated semantics.
For what it’s worth, these screenreader experiences aren’t hypothetical — they’re benefits that screenreader users really get from using <dl> in most browser/screenreader combinations. Admittedly, however, support for the <dl> element is not yet universal. You may decide that screenreaders’ fallback experience — treating the list as standalone text nodes — isn’t sufficient for your use case, and instead opt for something like a <ul> until support improves.
Okay, Okay, One Last Example!
My favorite example, the one that really takes the cake for me, is Dungeons & Dragons statblocks, which are really “Oops! All Name–Value Pairs!”
No, really: just how many candidates for <dl>s do you see in this statblock alone?
I counted five possible description lists, personally. Here’s how I chose to mark this up:
<div> <h1>Kobold</h1> <small>Small humanoid (kobold), lawful evil</small>
<dl> <div> <dt>Armor Class</dt> <dd>12</dd> </div> <div> <dt>Hit Points</dt> <dd>5 (2d6 – 2)</dd> </div> <div> <dt>Speed</dt> <dd>30 ft.</dd> </div> </dl>
<dl aria-label=“Ability Scores”> <div> <dt>STR</dt> <dd>7 (-2)</dd> </div> <div> <dt>DEX</dt> <dd>15 (+2)</dd> </div> <div> <dt>CON</dt> <dd>9 (-1)</dd> </div> <div> <dt>INT</dt> <dd>8 (-1)</dd> </div> <div> <dt>WIS</dt> <dd>7 (-2)</dd> </div> <div> <dt>CHA</dt> <dd>8 (–1)</dd> </div> </dl>
<dl aria-label=“Proficiencies”> <div> <dt>Senses</dt> <dd>Darkvision 60 ft.</dd> <dd>Passive Perception 8</dd> </div> <div> <dt>Languages</dt> <dd>Common</dd> <dd>Draconic</dd> </div> <div> <dt>Challenge</dt> <dd>1/8 (25 XP)</dd> </div> </dl>
<dl aria-label=“Traits”> <div> <dt>Sunlight Sensitivity</dt> <dd> While in sunlight, the kobold has disadvantage on attack rolls, as well as on Wisdom (Perception) checks that rely on sight. </dd> </div> <div> <dt>Pack Tactics</dt> <dd> The kobold has advantage on an attack roll against a creature if at least one of the kobold’s allies is within 5 ft. of the creature and the ally isn’t incapacitated. </dd> </div> </dl>
<h2 id=“actions”>Actions</h2> <dl aria-labelledby=“actions”> <div> <dt>Dagger</dt> <dd> <i>Melee Weapon Attack:</i> +4 to hit, reach 5 ft., one target. <i>Hit:</i> (1d4 + 2) piercing damage. </dd> </div> <div> <dt>Sling</dt> <dd> <i>Ranged Weapon Attack:</i> +4 to hit, reach 30/120 ft., one target. <i>Hit</i>: (1d4 + 2) bludgeoning damage. </dd> </div> </dl>
</div>
This is just one way you could have opted to mark up that statblock.
I love this as a demonstration because it really goes to show just how versatile the description list pattern can really be — the lists of ability scores (STR, DEX, and so forth) and attacks both look very different, and yet, the description list pattern can span them all.
Takeaways
Lists of name–value pairs (or, in some cases, name–value groups) are a common pattern across the web, in part due to their versatility. HTML lets us mark up these lists with a combination of three elements:
The <dl>, or description list, element, which wraps the entire list of name–value pairs
The <dt>, or description term, element, which represents a name in our name–value pairs
The <dd>, or description detail, element, which represents a value in our name–value pairs
Ascribing semantics to patterns such as these gives our users’ devices the information they need to curate useful, usable experiences — oftentimes in ways that we as developers may not expect.
To learn more about description lists and what’s allowed or not allowed, I recommend the MDN docs on the <dl>, or going directly to the specs!
Footnotes
Prior to HTML5, this was called a definition list. This is because the <dl> was originally only intended to represent glossaries of terms and their definitions. | Back to [1]
Prior to HTML5, this was called a definition list. This is because the <dl> was originally only intended to represent glossaries of terms and their definitions. | Back to [1]
Previously known as the definition term and definition detail elements respectively. | Back to [2]
Previously known as the definition term and definition detail elements respectively. | Back to [2]
I have an attention problem.
A couple of weeks ago, I decided to convert my old laptop into a writerdeck, a dedicated writing device free from the distractions of the modern internet.
Lots of folks build really elaborate offline devices for this, and I’d love to do that… someday. Right now I have no shortage of projects and the point is to get writing, so I used what I had: a six-year-old laptop which still runs great, has plenty of power, but isn’t getting much use anymore.
Crucially, this laptop has an excellent keyboard, and a matte screen, which makes it awesome to type on for long stretches, and functional enough in the daylight (I like to sit outside with my dog and write). It’s also a System76 Galago Pro (not sponsored), which means it’s already Linux friendly and has great support in the kernel.
Setting up a tty instead of a desktop
Now, you could certainly just use a regular desktop OS and keep it offline, although that’s easier said than done. I don’t think you can fully remove the browsers from a modern Mac or Windows PC. At least not in a supported way.
Of course, I’m a Linux user, and I have any number of options. I could have gone with a simple desktop or window manager and just not installed a browser, but I wanted something that really broke the desktop OS muscle memory and forced me into thinking about my words with intention.
I opted for a tty-based setup, using Debian (Trixie at the time of writing). Console only- no x11 or Wayland, no desktop getting in my way.
Installing Debian is easy enough. I use the text-based installer mode, and for this writerdeck, I opted to skip full-disk encryption (there’s nothing on this device that isn’t going to be public anyway).
Folks always tell me they get hung up on things because they don’t set themselves up with sudo on Debian. If you’re coming from Mint or Ubuntu or virtually any other desktop-oriented distro, this could trip you up. If you want to use sudo for admin tasks, skip adding a root password. That’ll disable root and set you up as a sudo user.
On the desktop setup screen, I chose to remove all desktop features, because again, I want this thing to be a minimal device. Just me and the words, no GUI getting in my way.
When things wrap up, you’ll be greeted with a bland console login. Perfect place to get started.
Installing network-manager
After signing in for the first time and making sure I was up-to-date with a quick sudo apt update and a sudo apt upgrade, I chose to replace the regular network stack with the network-manager package. Mainly to get access to the very good curses tool nm-tui for connecting to networks.
nm-tui is a thousand times easier than editing config files for setting up network devices. And while I will be working mostly offline with this device when I’m away from home, I do appreciate the ability to connect it to the network to back up files should the need arise.
After installing network-manager with sudo apt install network-manager, you can use nm-tui to scan for available Wi-Fi networks and get hooked up. Depending on your hardware, you might also have WAN access here. Pretty cool.
Installing neovim and kmscon
I couldn’t wait any longer, I installed neovim as soon as I could with sudo apt install neovim. I didn’t want to edit with nano. Nothing personal, I’m just a vim user all the way now.
Normally I use traditional vim but I opted for neovim as I’m trying to get to know it a bit more.
Then, I installed kmscon, which for Debian Trixie needed to be added from backports.
First, I updated my Debian source list by editing the file at /etc/apt/sources.list to add the following two lines:
deb http://deb.debian.org/debian/ trixie-backports main contrib non-free non-free-firmware deb-src http://deb.debian.org/debian/ trixie-backports main contrib non-free non-free-firmware
A quick sudo apt update and then I can simply run sudo apt install -t trixie-backports kmscon. This will install the kmscon package from backports, as well as its dependencies, and set it to automatically start on boot. Next reboot, you’ll see the familiar tty, but now it’s scalable with ctrl-plus and ctrl-minus, like most modern web browsers.
From here, I have a totally functional writerdeck. I could be done here and be reasonably satisfied with an offline, pleasant writing experience. But I wanted a few more nicities which I’ve grown accustomed to.
tmux for multiplexing and a pretty status bar
Next, I installed tmux for basic terminal tiling and a pretty status bar. This is packaged for Debian (and virtually everyone else), and is installed with sudo apt install tmux.
I also installed acpi for battery details, and light to control the screen backlight. You can install these at the same time with sudo apt install acpi light. I set these up in my .tmux.conf file, which is kept in your home directory. Here’s how I used them.
ACPI for battery readouts
Once the acpi package is installed, you should be able to see your battery with acpi -b (assuming your laptop has a battery which is detected with acpi, which has worked so far on every laptop I’ve tried in my house).
So, to get the specific percentage and nothing more, you can pipe acpi -b into grep like so:
acpi -b | grep -m1 -o -P ‘.{0,2}%’
This grep is a bit hard to understand, so let’s break it down:
-m1 says stop reading the file after one line. I did this because some laptops I’ve used have multiple batteries, and I only care about the primary battery. You can probably leave this out if acpi -b only returns a single line.
-o prints only the matched parts of the line. I don’t want a large printout with the remaining time. You might!
-P interprets the pattern as a Perl-compatible regular expression. Then ‘.{0,2}%’ gets us the percent sign and the two numbers preceding the percent. (This won’t show “100%” but I can live with that, because this laptop doesn’t get there anymore.)
I wanted to replace the default details in the tmux status bar with a battery readout, so I do so with the following in my .tmux.conf:
# give me a battery readout instead of the time set-window-option -g status-right “#(acpi -b | grep -m1 -o -P ‘.{0,2}%’)”
Light for brightness
Next, we can use the very simple light command we installed earlier to control the brightness. On my laptop, F8 and F9 have brightness indicators printed on the keys, so it’s a perfect fit.
light -U 10 decreases the brightness by ten percent, and light -A 10 increases it.
So, to bind F8 and F9 to decrease/increase brightness control, I simply add this to my .tmux.conf:
# keybinding for brightness bind -n F8 run-shell ‘light -U 10’ # decrease bind -n F9 run-shell ‘light -A 10’ # increase
Now, next time I start tmux, I’ll have brightness controls. Very neat!
Additional tmux customization
Lastly, I like the status line for tmux at the top of the screen, because neovim puts a status line at the bottom of the screen. That’s achieved by adding set -g status-position top to the .tmux.conf file.
Also, I have a habit of specifying the color. I think it’s green by default but I set it anyway (I might change it in the future, who knows) with set -g status-style bg=green.
So, my final tmux.conf looks like this:
# bar position and color set -g status-position top set -g status-style bg=green
# keybinding for brightness bind -n F8 run-shell ‘light -U 10’ # decrease bind -n F9 run-shell ‘light -A 10’ # increase
# give me a battery readout instead of the time set-window-option -g status-right “#(acpi -b | grep -m1 -o -P ‘.{0,2}%’)”
This isn’t a tmux lesson, but by default, to do a split, you use Ctrl-B to break out of regular mode and into the tmux command mode, and then the % key to split vertically, or ” to split horizontally. Ctrl-B, then an arrow will move your focus between panes.
Someday, I’ll do a formal tmux lesson. Moving on!
neovim and vimwiki
I know a lot of folks won’t want to use neovim or vim, opting instead for emacs or helix or micro or nano or blammo or something else I didn’t mention (but someone’s about to).
That’s great. I’m happy for you. I’m a vim user though, so that’s what I set up.
neovim includes some reasonably great colorschemes which you can try out with the :colorscheme option. I chose blue, which fit my retro vibe just fine, but you could pick anything you want or even write one yourself from scratch.
I added that to my .config/nvim/init.vim file with colorscheme blue, and I also added set linebreak so that way words would wrap to the next line (I don’t normally do this on my desktop but this thing’s one job is writing).
Lastly, I set up vimwiki, which I already covered in a separate %blog post%. The only thing that’s changed is instead of installing vimwiki with a plugin, on Trixie it’s packaged, so you can install it with sudo apt install vim-vimwiki.
Installing Syncthing
I set up syncthing according to the Syncthing docs, which are pretty good and I won’t repeat those too much here.
I set up syncthing to connect my writerdeck’s vimwiki folder to my server’s writing folder, which is a subdirectory inside another, more private vimwiki setup. I do it this way so that if there’s sensitive notes in my desktop vimwiki, they don’t sync to the writerdeck. If I had encryption on this device, I wouldn’t mind that though, and I might set up password-based LUKS encryption just to gain access to my vimwiki diary on the writerdeck.
The one place where I strayed from a stock syncthing setup is that because I don’t have a desktop with a traditional browser, I had to set my syncthing web GUI to be listening on all addresses instead of just 127.0.0.1. I don’t love this approach, but again, this thing has nothing private on it. A better way would be to set up a SOCKS proxy and connect that way, but that’s a topic for a future post.
Setting it up to autologin
The last thing I did to make this writerdeck my own was to set up automatic login.
I want to be able to open this up and start writing quickly- autologin is a simple way to get there.
Autologin with kmscon
Because I installed kmscon, this is pretty easy, just update the (gasp) systemd service with sudo systemctl edit kmsconvt@tty1.service.
Then, I just added the following:
[Service] ExecStart= ExecStart=/usr/bin/kmscon –login — /bin/login -f my_username_goes_here
This tells kmscon to start what comes after the — after –login. In my case, that’s the default /bin/login program with the parameter -f and then my username.
Launching tmux on boot
After kmscon signs me in, I want tmux to automatically launch into vimwiki. But only if I’m on the main tty (the default virtual terminal).
I can do this easily by adding a small bash if/then to my .bashrc:
# Launch tmux if we aren’t already running tmux and we’re in the default tty if [ -z “${TMUX}” ] && [ $(tty) == “/dev/pts/0″ ]; then exec tmux new-session -d ‘vim -c VimwikiIndex’ \; attach fi
This works by checking to make sure we’re not in tmux already (which would be recursive and bad), and it also makes sure we’re in the first virtual tty. If those two conditions are met, then it launches a new tmux session with the command vim -c VimwikiIndex (which tells vim to connect to the Vimwiki index). It then attaches to that session.
After using it for a few projects, I love it.
I’ve had this thing going for a week or so now, and I’ve used it to write this blog post, the script for the companion video, and another future script I’m working up right now. And it’s awesome.
I may extend this idea with a spell checker, or perhaps set up a “writerdeck terminal” in my workspace using an old 486, to really bring myself back to a more intentional experience (with an even better keyboard!).
The point is to write more, and to be less distracted doing so. I have always struggled immensely with the fact that the browser nags at me. I get notifications about apps needing my attention. My music player tells me the next song we’re playing. It’s all very convenient, and very distracting.
I’m trying to be more intentional with my tech choices. I want devices that do one thing really well, and that when I’m done with that one thing, I can put them away, and do something else. I don’t want everything to follow me around everywhere.
If that’s you, maybe you would benefit from a writerdeck. For me, it’s been great. :)
Tips
Book Freak #210: The Art of Money Getting
P.T. Barnum’s Golden Rules for Making Money
Get The Art of Money Getting
P.T. Barnum was 70 years old when he turned his most popular lecture into this book in 1880. By then, he’d already built America’s most famous museum in New York, introduced General Tom Thumb to audiences, served as mayor of Bridgeport, gone broke from a disastrous investment in a Connecticut clock company, and clawed his way back. He was 60 when he co-founded the traveling show that eventually became Barnum & Bailey Circus. The Art of Money Getting compresses a lifetime of hustle into 20 plainspoken rules.
Core Principles
1. Don’t Mistake Your Vocation
Barnum’s first rule: pick the work you’re built for, then aim to be the best at it. Most people get this backward. They take whatever job pays and spend decades fighting upstream. The people who succeed have a knack for what they do. Find your knack first.
2. Avoid Debt Like the Plague
Debt eats self-respect. Barnum says young people, especially, should avoid it. The moment you owe somebody money, you’ve handed them a piece of your freedom. The whole game is keeping income above outgo.
3. Whatever You Do, Do It With All Your Might
Half-doing is expensive. Barnum watched neighbors spend whole lifetimes poor because they only kind of worked, while somebody else got rich doing the same job thoroughly. The people who go all in pull ahead of the ones who don’t.
4. Preserve Your Integrity
Nobody buys from someone they don’t trust. You can be the friendliest merchant in town, but if a customer suspects you of cheating, they’ll walk to the next shop. Dishonesty might pay this week. It costs you over a lifetime. Reputation is the actual asset.
Try It Now
Examine your current work. Does it match your natural abilities? If not, what would? Make a plan to move toward it.
List your debts. Create a concrete plan to eliminate them, starting with the smallest. Avoid taking on any new debt this month.
Pick one task you’ve been half-doing. This week, do it with all your might. early and late, leaving no stone unturned.
Quote
“Money is, in some respects, like fire. It is a very excellent servant, but a terrible master.”
“Money is, in some respects, like fire. It is a very excellent servant, but a terrible master.”
Book Freak is published by Cool Tools Lab, a small company of three people. We also run Recomendo, the Cool Tools website, a YouTube channel and podcast, and other newsletters, including Recomendo Deals, Gar’s Tips & Tools, Nomadico, What’s in my NOW?, Tools for Possibilities, Books That Belong On Paper, and Book Freak.
05/22/26
For years, my desk was pushed against the wall. I would sit in front of it, look at the wall, and work. It was fine, and I never really questioned it.
After a recent trip to Hamburg, visiting various museums and exhibitions, something struck me. I hadn’t seen a single desk that was facing the wall. Almost every single desk was in the middle of the room, and facing the room itself.
Once I was back from my trip, I rotated the whole setup for my desk, and flipped it. Now my desk is facing the room. My back is against the wall, I can see the door, and I have the rest of the room in my field of view. It is a small change, but the space feels very different. I should have done this earlier.
From time to time people still message me of my desk photos that appeared on Instagram or X. Those photos are old now, and I actually changed my room setup quite a bit. The room looks different, and the desk has changed as well. Over the last months I started to think more carefully about what I want from a desk and how I spend time around it.
Rethinking the desk
Instead of having a single, tech only desk, I now use one large desk that is split into two parts: a digital side and an analog side.
For a long time my idea of a desk was simple: a place for a computer, monitor, keyboard, mouse, and some accessories. It was a work surface for technical tasks. Everything else had to adapt to that. Here is an old photo:
The problem is that this pulls every activity into the same mode. If you sit down, you are in front of screens. Even if you only want to read, think, plan, or write something by hand, the computer is right there and competes for your attention.
This also means that I always had to push away my keyboard if I wanted to have more space for writing or sketching.
I did not want to maintain two separate desks in the same room, but I also did not want the computer to dominate everything. A single, long surface with two clearly defined areas turned out to be a good compromise. So I researched and ended up with the one in the pictures, which is a 200x75cm long desk from USM Haller.
The idea is that, on one side I keep the digital tools. On the other side I keep the analog tools. They share the same piece of furniture, but they serve different purposes.
The digital side
The digital side is the part of the desk by the windows. It has the Studio Display, the Mac and my split keyboard (It’s the Elora Halcyon with my own custom design) This is where I spend most of my day writing, coding, and being on calls, so I try to keep it as empty as possible.
This area is intentionally minimal. Everything on this side is directly related to my day to day work. When I sit in the chair and slide over to this half of the desk, I know I am there to write, code, review something, or join a call.
This also changed how I think about adding new items. If something wants to live on the digital side, it has to be used regularly. If not, it moves to the other half of the desk or leaves the desk entirely.
The analog side
The other half of the desk is reserved for everything that does not need a screen. On a typical day, this part of the desk has:
A notebook or planner
A couple of fountain pens
Books I am currently reading
Loose sheets with sketches or diagrams
A desk lamp that nicely illuminates the surface (It’s the Artemides Tolomeo Mini, with my custom designed adaptor)
This is where I read, write in a journal, plan projects, or outline ideas. Sometimes I use it for small DIY projects. Sometimes it turns into a shared space with my kids, where we build LEGO or sit together and draw.
The analog side does not need to look minimal. It needs to be functional and inviting. It is a place where things can stay out for a while so I can return to them without having to pack everything away.
People following me for a long time know that I really like clean and minimalist design, but with time I realized that minimalism also kills creativity, or the passion to work on new things. Maybe it’s best to enjoy a mix of both, minimalism and maximalism, and adapt according to your needs.
Living with the setup
I have been using this two-part desk layout for about nine to ten months and I am very happy with it.
Facing the room instead of the wall makes the office feel more open and comfortable. There is now some sort of depth in front of my eyes, that was lacking previously. Also, having the door in front of me, instead of my back, feels also safer somehow.
Splitting the desk into a digital and an analog side creates a clear mental boundary. And moving the chair from one side to the other is enough to change the context.
I do not see myself going back to a tech only desk. This setup gives me a place to work, a place to think, and a place to spend time with my kids, all on a single surface.
Several times in the last couple of decades, Microsoft has released source code for the original MS-DOS operating system that kicked off its decades-long dominance of consumer PCs. This week, the company has reached further back than ever, releasing “the earliest DOS source code discovered to date” along with other documentation and notes from its developer.
Today’s source release is so old that it predates the MS-DOS branding, and it includes “sources to the 86-DOS 1.00 kernel, several development snapshots of the PC-DOS 1.00 kernel, and some well-known utilities such as CHKDSK,” write Microsoft’s Stacey Haffner and Scott Hanselman in their co-authored post about the release.
To understand the context, here’s a very brief history of what would become MS-DOS: Programmer Tim Paterson originally created 86-DOS (previously known as QDOS, for “quick and dirty operating system”) for an Intel 8086-based computer kit sold by Seattle Computer Products. Microsoft, on the hook to provide an operating system for the still-in-development IBM PC 5150, licensed 86-DOS and hired Paterson to continue developing it, later buying the rights to 86-DOS outright. Microsoft then licensed this operating system to IBM as PC-DOS while retaining the ability to sell the operating system to other companies. The version sold by Microsoft was called MS-DOS, and the proliferation of third-party IBM PC clones over the ’80s and ’90s made it the version of the operating system that most people ended up using.
Released at the Outline Demoparty in May 2026, Ommen, NL An exploration of algorithmic density in 16 bytes of x86 assembly.
Hey everyone. I learned programming as a kid on an old IBM PC with a monochrome green monitor over 30 years ago and always wanted to create a program for this system. I created well over 100 tiny intros in the last 15 years. Recently I was not too active but the fantastic “Rainbow Surf” from Plex in just 16 bytes motivated me to dig up some old dusty sketches again and get to work.
The creation of this program happened with the usual tinkering around. I was messing with cellular automaton for graphics and sounds and discovering sizecoding tricks. Actually: a) polymorphic asm instructions, like add [bx+si],al which is 0x0000 b) jumping into the middle of instructions to save bytes and reuse opcodes. In hundreds of tiny experiments, this one stuck out, just by the sound of it.
When I unfolded what’s left and removed “the rest”, I had a hard time to grasp what’s really going on. I was scratching my head looking at the simple formula that remained after golfing many bytes away. I myself didn’t expect that the explanation would go this deep for just these few bytes xD.
My original “M8trix” from 2014 already did smear pseudorandom letters across the screen (in 8 bytes, then in 7) and I always wondered how I could make it “sound good”. But chronologically in the development of “wakeup”, the sound was first. Since you “see what you hear” it doesn’t really matter, but “16 bytes that turn Sierpinski sound into Matrix rain” would be a good subtitle =)
TLDR: Each time step, another Sierpinski triangle line is a) played on the speaker b) drawn to the screen with a stepsize of 56. You can sense the motion, but not really see it, since it’s 8192 “pixels wide” but one line of chars is just 80 bytes. On a much much much bigger screen, you could see the triangle. Or, if you don’t “skip pixels” and draw it all at once, you would see it as well.
So, here are the 16 bytes of x86 real-mode DOS assembly. When you run it, it uses the video memory as a calculation space to draw an infinite Sierpinski fractal, and at the same time bangs the speaker with that geometry.
int 10h ; 2 bytes mov bh, 0xb8 ; 2 bytes mov ds, bx ; 2 bytes L: lodsb ; 1 byte sub si, byte 57 ; 3 bytes xor [si], al ; 2 bytes out 61h, al ; 2 bytes jmp short L ; 2 bytes
1. The Canvas: A Primed Void
The code starts with a standard BIOS interrupt: int 10h. This sets up video mode 0, giving a 40x25 text mode grid. Then the data segment (ds) is pointed to 0xb800, the memory address of the VGA/CGA text buffer.
When the BIOS clears the screen, it doesn’t fill memory with absolute zeroes. Every character space is two bytes: the ASCII character and the color attribute. All 2,000 slots are set to 0x20 (space) and 0x07 (light gray on black). So the screen looks empty, but the memory is already filled with a uniform pattern.
I created a lot of “noise” or “CA” sound intros but this one stands out. It was and is still super unexpected! The specific spice here is how memory is initialized on “clear screen” and what’s “before” and “after” the actual visible memory. The “pure” sound is also lovely (I can carefully set everything with a few more bytes to make it sound the same on all systems) but this spicy difference I still have to fully understand makes it sound even better imho =)
2. The Engine: Additive Prefix Sums
The intertwine, the synesthesia goes far beyond what I found so far in other tiny intros. I would even go so far as to say it’s revealing more mathematical secrets and relations than using iterated function systems for the “chaos game” without an RNG. Anyway, this time I want you to fundamentally understand the mathematics of what you hear. Not just “you do some operation here and then it sounds interesting”.
To strip it down to pure math: assume a zeroed state instead of 0x20, use add instead of xor, and step forward 16 bytes at a time. Assume the accumulator al starts at 2.
A DOS segment is exactly 65,536 bytes. Moving 16 bytes per step means exactly 4,096 steps to traverse the segment (\( 65536 / 16 = 4096 \)). Then si wraps cleanly back to 0x0000.
Adding up values between cells creates partial sums. Because 4,096 is a multiple of 256 (the 8-bit register size), the carryover aligns perfectly when the segment wraps, cleanly resetting al to 2 at the start of each sweep.
The value follows a binomial sequence, scaled by 2:
$$A^{(p)}[k] \equiv 2 \binom{k+p}{p-1} \pmod{256}$$
Here is how the first 16 steps accumulate row by row:
3. Crystallization: XOR and the Sierpinski Shift
Now, back to combinatorics. By special laws, when doing modulo two, the Sierpinski triangle emerges. This specific bit is what gets banged into the speaker, while the other bits are ignored.
To separate the bitplanes, the fact that carry-free addition of bits is XOR is why it is there instead of add.
Since the code starts with 2 (binary 00000010), only bit 1 is toggled between 0x00 and 0x02. This perfectly maps to rule 60 in elementary cellular automata:
$$Cell^{(p)}[k] = Cell^{(p-1)}[k] \oplus Cell^{(p)}[k-1]$$
Lucas’s theorem guarantees this matches bit 1 from the addition table. See for yourself (‘2’ means bit 1 is set):
4. The Voice of the Machine: Translating Data to Audio
Here is the trick: out 61h, al
Port 61h interfaces with the PC speaker. Bit 1 pushes the speaker cone out (1) and pulls it in (0). The code computes the fractal via XOR, writes it to memory, and shoves that byte straight into the speaker port.
The 1s and 0s from the fractal create square waves that shift naturally in pulse width and frequency:
When played linewise, this creates self-similar, almost tempo-invariant bytebeats.
But it gets better: not only the text is output to the speaker but also the remaining bytes of the 64 kilobyte segment, which in this case also contains shadowed video ROM BIOS code, which is the secret ingredient to the punky and gritty sound that differs quite a bit from the expected Sierpinski line based overlayed rectangle wave bytebeat.
5. The 56-Byte Step: Octave Shifts and Diagonal Shears
To recreate the M8trix effect, the cells themselves have to be splat across the screen in a way that the sound buffer is not too large and the screen is nicely sparsely filled with chars.
So the code doesn’t step by 16. sub si, byte 57 plus lodsb means it moves -56 bytes per iteration - going backwards.
The Audio
56 doesn’t divide 65,536 evenly. The code only hits offsets that are multiples of 8, taking 8,192 steps and wrapping 7 times before resetting. This doubles the cycle length, halving the fundamental frequency. The sound drops one octave.
The Visuals
Moving back 56 bytes on an 80-byte wide screen is like moving forward 24 bytes (12 columns). Only 10 distinct columns are visited. The fractal isn’t drawn as a solid image; it shears diagonally into 10 pillars of characters moving up the screen.
6. Real Hardware and Final Thoughts
The scener miragept did a capture with this motivation:
“This is so awesome that I had to try running it in real hardware. The green text is a natural fit for MDA/Hercules, so I patched the address from 0xB800 to 0xB000 which is what MDA uses. I don’t have the exact IBM computer, but used a 286 with EGA card capable of emulating MDA/Hercules, and a real MDA monitor, so it’s close enough. Sorry for the low quality audio (the constant noise is from the machine itself). Please note that this monitor (IBM 5151) has a HUGE phosphor persistence, which I think hurts the presentation in this case because it’s very fast.”
Sorry for the low quality audio (the constant noise is from the machine itself). Please note that this monitor (IBM 5151) has a HUGE phosphor persistence, which I think hurts the presentation in this case because it’s very fast.”
My reply to him:
“HellMood @miragept: Thank you so much for this ♥ I’m happy to see it works like intended, even with a slightly different sound due to the byte change. Maybe it would indeed be a bit better to have it run slower, but what I found remarkable is, that the Sierpinski structure becomes actually more visible (towards the end) than in my version =)”
Emulators and different BIOS versions leave slightly different artifacts in RAM. Since the code XORs against whatever is there, the output is highly sensitive to the environment. Clearing the memory first would give a perfectly uniform output, but that costs precious bytes. Embracing the hardware’s natural state is just part of the charm of sizecoding. Thanks for reading.
Links & Resources
Nanogems - A curated selection of the best Tiny Intros from the Demoscene
HellMood’s productions on Pouet
Capture on a 286/MDA/Hercules by miragept
Sizecoding Wiki
“Rainbow Surf” - 16 bytes of x86 by Plex
“M8trix” - 8 bytes by HellMood
This text is handwritten.
Last year, health wearable maker Oura became embroiled in a social media shitstorm after inking a deal with the Department of Defense and Palantir. Some customers feared their data would end up in the clutches of the Trump administration. The scandal blew up so much that my partner, an Oura ring user, drew my attention to it.
Oura rings are health-monitoring hardware wearables worn on a finger. These battery powered rings keep track of a person’s health data, like heart rate, sleep patterns, menstrual cycles, and dozens of other data points, including their location. Oura keeps a lot of sensitive information about its users on its servers.
As a security and privacy nerd reporter, and the partner of someone who uses hers, I wondered: Where does all that data go, and how does it get there? You might assume it doesn’t matter. But the way that companies set up their products and servers makes all the difference between whether governments (or hackers) can also access that user data.
This was a good opportunity to dig into how Oura rings work, how they send data and how the data is stored, and who has access to it. I wrote a detailed longread explaining why Oura’s security design choices allow governments to tap records from Oura’s vast banks of user information.
Oura is not unique in this, and many (if not most) companies design their systems to allow their staff to access user data, perhaps for troubleshooting customer issues or because it was the easiest and cheapest setup for a once cash-strapped startup. But Oura is now one of the largest health tech wearable makers today, valued at over $11 billion ahead of going public. The company has a responsibility more than ever to ensure that its users’ data cannot be accessed. And, Oura can no longer argue that it does not have the financial resources to do it.
In my previous blog, I revealed that Oura data is not end-to-end encrypted. That means that an Oura user’s health data can be unscrambled at certain points as it travels from a person’s ring, through their phone app, over the internet, and as it lands on Oura’s servers. The company confirmed that it stores user data in a way that allows some staff to access it. This also means others can as well, such as a prosecutor with a warrant, a hacker with stolen keys, or a disgruntled insider who wants to leave behind a fustercluck of a mess.
Out of the three, we know at least one of those things has happened.
When I reached out for comment before publishing my last article, an Oura spokesperson told me that the company does “receive infrequent requests from the government.” Oura said it looks at each request “for legality, scope, and necessity,” and that it pushes back “where requests are invalid, overbroad, or inconsistent with our commitment to protect our members’ privacy.”
Oura would not say how many requests it receives, how often it turns over user data, or what kinds of data are requested. Oura has sold over 5.5 million rings to date as of around the time of my last article, giving some scale to the size of the company’s customer base.
I asked Oura back then if it would disclose how often it received these requests, such as by publishing a transparency report. A wave of tech companies began releasing in aggregate how many government demands they received on a semi-annual basis. This was largely to counter the claims that they were secretly handing over reams of user data to the government upon request, stemming from the NSA surveillance scandal in 2013.
There was some hope in Oura’s initial response. A spokesperson told me at the time that while Oura does not publish a transparency report, the company said it was “actively evaluating how to share aggregate data in a way that maintains security and does not introduce risk to our members.”
It’s been eight months, dear reader.
I recently reached out to Oura again to see if it would release a transparency report, and after several follow-up emails, the once-responsive Oura has not yet replied to any of my inquiries, or committed to releasing the numbers. I’m hopeful that Oura will reconsider and publish how many demands it receives as other tech companies have.
Without seeing the numbers, it is impossible to know how often, if ever, Oura rejects government demands for data. As the frontrunner in the health wearables market, Oura should share how often the government demands access to users’ information if it wants to earn or keep the trust of its customers.
~ ~
Thank you so much for reading ~this week in security~. If you liked this article, please share it! Feel free to reach out with any feedback, questions, or comments about this article: this@weekinsecurity.com.
To add this web app to your iOS home screen tap the share button and select "Add to the Home Screen".
10HN is also available as an iOS App
If you visit 10HN only rarely, check out the the best articles from the past week.
Visit pancik.com for more.