Latest Posts (20 found)
Luke Hsiao 3 weeks ago

Switching from GPG to age

It’s been several years since I went through all the trouble of setting up my own GPG keys and securing them in YubiKeys following drduh’s guide . With that approach, you generate one key securely offline and store it on multiple YubiKeys, along with a backup. It has worked well for me for years, and as the Lindy effect suggests, it would almost certainly continue to. But as my sub-keys were nearing expiration, I was faced with either renewing (more convenient, no forward secrecy ) or rotating them (rather painful, but potentially more secure). However, I’ve realized that I essentially only use these keys for encryption, and almost never for signing. So, instead of doing either of the usual options, I’m going to let my keys expire entirely. I’m now experimenting with , which touts itself as “simple, modern, and secure encryption”. If needed, I will use for signatures. This required changing a couple of things in my typical workflow. First, and foremost, I needed to switch from to , a fork of that uses as the backend. This was actually surprisingly easy because includes a simple bash script to do the migration. There is no installer for , and no Arch packages. But it’s easy enough to install because it’s just a shell script you can throw on your . Note that for Arch, I also needed to install , which it assumes you have. I also name as on my machine. The benefit of this is everything that had integration has continued to “just work”. For example, , my email client of choice, behaved exactly the same after the migration. I would occasionally use as my SSH agent on my machines. It was convenient. However, I also like the idea of having a dedicated SSH key per machine. It makes monitoring their usage and revoking them much finer-grained. The absence of forced me to set up new keys on all my machines and add them to various servers/services. Easy encryption with chezmoi While I was tending to the encryption area of my personal tech “garden”, I also started leveraging chezmoi’s encryption features . I already use for my configuration files, but with encryption, I could also easily add “secrets” to my public dotfiles repo . In my case so far, this just means my copies of my favorite paid font: Berkeley Mono . also has a nice guide for configuring chezmoi to encrypt while asking for a passphrase only once for . I was also very pleasantly surprised with how easy it was to switch to ! Last time I set up the GPG keys on my YubiKeys, I spent several hours. This time, with the help of and embracing the idea of having unique keys on each YubiKey, but encrypting everything for multiple recipients, setting up my keys was surprisingly trivial. It also generates the keys securely on the hardware key itself, which is nice. The whole process probably took 30 minutes. It was so easy that in the future, I’m very much not intimidated by the thought of rotating keys. Did I need to switch to ? Of course not. However, over my career, I repeatedly find that exploring new tools for your core workflows (part of investing in interfaces ) is just plain fun. I often learn new ways of thinking about problems. Sometimes, you walk away with a new default that brings some fresh ideas and some delight to your life. Other times, you walk away with your trusty old tool, with greater appreciation for its history and the hard-earned approach it has established. For my uses at the moment, definitely falls into the former camp.

0 views
Luke Hsiao 1 months ago

First impressions of jj from a git fan

Jujutsu ( ) is a distributed version control system (like , , , , etc.). However, it is rather unique in that it is -compatible—it uses as a storage layer, meaning you can use it right now on your existing repos without disrupting anyone else. It also provides other features, such as It also clearly has a (currently small but) passionate group of users, which is a good sign of a useful tool. Some of these users strongly dislike , finding its user interface unintuitive and clunky. I, however, am very much not part of that group. I love . Over the years, I’ve curated a configuration that I find a joy to use. I’ve built up years’ worth of muscle memory. As a result, even though I love investing in interfaces , such as new software tools, I haven’t ever felt motivated enough to try . That changed this past week when I learned that Steve Klabnik found so interesting that he’s leaving Oxide to pursue it further . As an experiment, I’ve committed to using only for at least a couple of weeks. As a user, the tutorial that clicked best for me is Steve’s . So, if you’re a fan, I suggest starting there. What I miss from I quickly ran into two features that I wish were supported. First, does not support submodules . Sure, submodules are not great in many cases. However, one very common case I use them for is Zola themes, such as the theme for this blog. My customization lives in my repository, and the theme for the site lives in a submodule. However, it looks like they are working on that actively and with great care. Second, I missed . This one is more minor, because I can always just fall back to to do so. Even in just a few days, I’ve wanted to serialize a patch to a file (i.e., ) or apply some patch I have sitting around with . One example is a patch file I keep around that customizes an environment for debugging purposes. As a -native approach, I’ve been keeping a change separate that I can rebase into my patch series and move out later if needed, but that feels clunkier. Then, there are a handful of more rarely used things that I have not needed yet, and consequently have not figured out equivalents for. For example, I’m not sure about an equivalent for view release notes via tags. With , I used an alias like But, then it seems right now doesn’t support anything but simply listing tags right now. No creation or deletion. Ouch. I’m not sure an equivalent for . Most likely would need to build some template. I don’t have some equivalent of . But again, it’s -compatible, so I can just keep using . I’m sure there will be a long tail of things like this. Steve and others have described as “both simpler and easier than git, but at the same time, it is more powerful.” I’m not sure I fully agree. In some ways, it has better defaults (e.g., , ), but in other ways, it is complex (e.g., revset language). That said, I do see how it is more powerful. You cannot exactly your mental model to directly onto ’s. That said, one of the main things I enjoy at $WORK is that for a repository, ’s default “view” (for lack of a better word) is a branch, whereas ’s default view is much higher level. I find ’s approach more intuitive: it’s always pretty trivial to see what branches/PRs I have ongoing at a glance (i.e., with ). It also means you can easily do fun stuff like rebase all of your branches at the same time, and push them all simultaneously to your remote! This is made even better by the fact that conflicts are first-class objects, meaning you can rebase all your branches, and deal with conflicts later. In a similar vein: emphasizes commits or changes in a way I find pleasing. Even though in I have ways to do similar things, does indeed make them easier. For example, splitting one commit into multiple is easier. In , you’d probably do something like In , just does the more intuitive thing. Instead, the same process looks more like As another example, I’m a huge fan of . It makes folding follow-up changes into an appropriate earlier commit easy and effective. However, it isn’t built into . Meanwhile, ships with , which does the same thing. I found that in , I was already following a workflow close to the squash workflow recommended by ’s creator, Martin. The main thing I still feel clumsy with is named bookmarks (similar to branches). Specifically, I find it hard to remember to the bookmark when I make updates, and how to rebase them without looking up commands. That said, it’s becoming more familiar over time. Much like , I’ve also found that ’s defaults aren’t entirely sufficient for me. I needed to make some tweaks. You can see my up-to-date dotfiles here , but as a snapshot, these are changes I found to be particularly valuable right from the start. First, I strongly prefer over the default viewer. also makes it easy to view with another tool with . For example, I also like using . I added a config from this discussion so doesn’t clear the screen on quit. Second, I like having my conventional commit template automatically populated on . I also have the diff included , which mimics the config I had with using Third, I changed the default bookmark prefix to . Finally, I added a bunch of aliases I use frequently. I use to copy-paste commit descriptions into PR descriptions. I use to view all the logs most relevant to me. This was discovered courtesy of Will Richardson . I use to view all logs. I use and to push all my bookmarks, and rebase all my changes on main, respectively. Finally, I use to move my bookmark to the latest change (I found this one thanks to Shaddy ). I actually find quite fun! Again, I do not think it “solved” any pain points I had with . I was already a very happy user. Ultimately, ’s interface and mental model do feel refreshing enough that I’m likely to continue using it. conflicts as a first-class object no explicit index revset language operation log and powerful undo automatic rebase and conflict resolution

0 views
Luke Hsiao 1 months ago

ASUS PA32QCV: a programmer's first impressions

Those who know me know that I invest in interfaces . Previously, I had an LG 38GN950-B (38“ Ultrawide, 3840×1600 @ 144Hz). It was expensive, but had a little extra vertical resolution vs its competitors, and the high refresh rate was great for casual gaming. But, over the years, I play games less, and my eyes are aging! I find myself appreciating larger and more crisp fonts for programming. With that in mind, I started looking for a high resolution “retina”-class display. There are only a handful of these around at the time of writing. In the 27“ 5K group: Apple Studio Display / ProArt PA27JCV / Samsung S9 / Kuycon G27P . Then, there is the 32“ 6K group: Apple XDR / ProArt PA32QCV / Kuycon G32P / Dell U3225KB / LG 32U990A-S . Then, there is the even more sparse 8K group: Dell UP3218K / ProArt PA32KCX . I know I wanted to avoid fractional scaling, so I was searching for either 6K or 8K. I immediately discovered that 8K is way out of my price range. In the land of 6K, this ProArt PA32QCV met a sweet spot: (1) being available for purchase right now, (2) having relatively modern hardware, and (3) not being ridiculously expensive. So, I bought it. I’m a big fan. As soon as I switched, I understood why people like these high-resolution displays. Text is crisp and delightful to look at! I do not miss the ultrawide at all. I run at 2× scaling, and have been loving looking at it. Yes, I do notice the drop from 144Hz to 60Hz. However, because I’m mostly programming, I really don’t notice it during a typical workday unless I go looking for it (e.g., dragging a window quickly). The colors look great. In other words, when it comes to the display itself, it seems fantastic, which is what I was looking for. Some people complain about the matte “LuxPixel” finish. I think it looks fantastic, and appreciate the lack of glare. This is a bonus, not an issue. When it comes to some of the other features, they are notably less useful. These are fairly awful, as one would expect. What confuses me is why these are here at all. This is a “pro” monitor, and I see no value in having speakers. I wish they saved some cost or reduced size/weight instead. I frequently multiplex between a work laptop and a personal desktop. So, a built-in KVM is actually very appealing! However, I’ve never found one that works well for my needs, so I’ve always reverted to separate display cables and a USB switch. The same is true here. Yes, this monitor has a KVM, but it does not have enough USB ports for my needs. It has 3 USB ports, and 1 thunderbolt port. The good news is that this lets me use 4 USB devices just fine on MacOS. The bad news is that the 1 thunderbolt port does NOT work on my desktop, leaving me with just 3 devices. Typically, I want four: a mouse, keyboard, webcam, and audio interface. Five, if you count a security key. So, good idea and will work for just a keyboard an mouse, but not enough for me. Another fatal flaw is that the KVM doesn’t appear to activate immediately upon switching input. This is vital because if your other machine goes to sleep, the input button will not switch until there is a display signal on that input—a signal that you have no way to initiate without a keyboard or mouse active! With a USB switch, that means I typically switch, wake up the machine, and then switch the input. With the built-in KVM, that means there is simply no way to actually switch without waking up the machine first some other way. Not cool. The “Light Sync” feature actually sounded great: I work right by a window, and frequently do adjust brightness to compensate for the ambient light. It would be awesome if it could do it for me! However, after using it, as far as I can tell there is no way to set the baseline/target brightness you want. Instead, it ranges from acceptable (in color preset) to unusably dim (in ). It is a good idea, but the implementation seems to only be viable in mode of the ones I tried, which means this forces you to make a color preset tradeoff. Instead, they should’ve just let me set the target brightness. Some features/design choices I was pleasantly surprised at. Not surprised they existed, but surprised how much I liked them. The box came with the display itself, a stand, a Thunderbolt 4 cable, an “ultra 8K” HDMI cable, and a power cable. After reading Michael Stapelberg’s review of the 6K Dell , I was a little worried about compatibility. I was optimistic that with a brand-new release, more compatibility issues would’ve been ironed out. I have two machines I use with this display: an M1 MacBook Pro, and my custom workstation (Radeon RX 7800 XT), running both Windows and Linux. The monitor was clearly built with a MacBook in mind. Using the Thunderbolt 4 cable, I instantly got power and display—full 6K no problems. Colors do indeed seem highly matched with the color preset. On my desktop with Windows via the included HDMI cable there was no problem. It instantly recognized full 6K@60Hz. My desktop with Linux via the included HDMI cable? No 6K at all. I first went down a bit of a rabbit hole assuming it was a Linux software issue (the same hardware works with Windows!). But, I’m running Arch, with a very recent kernel and all up-to-date drivers. I decided to try a DisplayPort cable instead. Whew! Instantly recognized the 6K@60Hz. So, that’s the tip: use DisplayPort on Linux. So far, after a couple days of use, I’m very pleased. We’ll see how it fares long term. I really like buttons being on the front of the monitor, rather than needing to blindly click around on a side or bottom. No giant power supply! I appreciate the saved desk space of having the power supply built-in.

0 views
Luke Hsiao 1 months ago

AI etiquette

I recently read a great blog post from Alex Martsinovich . It expressed a concept that I’ve been feeling, too: proof-of-thought . For the longest time, writing was more expensive than reading. If you encountered a body of written text, you could be sure that at the very least, a human spent some time writing it down. The text used to have an innate proof-of-thought, a basic token of humanity. Now, AI has made text very, very, very cheap. Not only text, in fact. Code, images, video. All kinds of media. We can’t rely on proof-of-thought anymore. Any text can be AI slop. If you read it, you’re injured in this war. You engaged and replied – you’re as good as dead. The dead internet is not just dead it’s poisoned. So what do we do? Luckily for us, AI only talks in response. Unlike Earth, AI does not emit comedy sketches into outer space on its own. To get AI slop, somebody needs to ask for it. To send it further, someone needs to retransmit it. Our problem is other humans, really. There’s nothing wrong with using AI. When you do, you know what you’re getting. The transaction is fully consensual. But whenever you propagate AI output, you’re at risk of intentionally or unintentionally legitimizing it with your good name, providing it with a fake proof-of-thought. In some cases, it’s fine, because you did think it through and adopted the AI output as your own. But in other cases, it is not, and our scrambler brain feels violated. He goes on to propose a simple new sense of etiquette: AI output can only be relayed if it’s either adopted as your own or there is explicit consent from the receiving party , otherwise, it is horribly rude. I’d add that essentially, you either are providing proof-of-thought, or, you’re explicitly acknowledging the lack of it. This resonates. It reminds me of Neven Mrgan’s reflection on how it feels to get an AI email from a friend . Recently I received an AI-written email from a friend. It wasn’t sent to test AI, or to show it off, as in “ha ha check this out”; my friend had a question to ask me, and the email asked it over the course of a few paragraphs. It then disclosed that, oh by the way, I used AI to write this. My reaction to this surprised me: I was repelled, as if digital anthrax had poured out of the app. I’m trying to figure out why. He then really breaks down how it did and didn’t feel as a recipient. For example, it didn’t feel like they were using it as an autocorrect to type better. It did feel like a family fridge decorated with printed stock art of children’s drawings. Years from now, could an AI that was trained on all of my friend’s emails and texts and personal documents sound convincingly like them? Could it be so advanced that I wouldn’t even be able to tell that my friend hadn’t written to me at all? Possibly. And that idea saddens me the most. The words on this blog have been and will always be, manually and intentionally typed by me (on a keyboard that delights). Yes, I am a big em dash (and en dash!) user—I even have macros in my editor to make the substitutions. No, that’s not AI. Yes, you’ll find typos and grammar errors in my posts; I’m human (but if you do, please send me a note so I can fix it). Still, I find writing a good way to clarify my own thoughts and, while I primarily write for myself, occasionally someone else benefits, too. While we have no formal way to prove proof-of-thought, my pledge to both you and myself is that this place will remain a place for human thought.

0 views
Luke Hsiao 2 months ago

Repairing my Windows bootloader after Omarchy

Before I switched to Omarchy, I was running on one NVME drive, and Windows on another. Part of this is because I want to use full disk encryption, and part of this is because I was originally playing with Project Bluefin , which doesn’t support dual-boot off of a single disk. I installed Omarchy via online ISO, and pointed it at my Linux drive. After it installed, I no longer could boot into Windows. My BIOS didn’t even show the 2nd NVME drive as a boot option. After some digging, I figured out a way to get things back without needing to reinstall any operating systems. My system looked like this after the Omarchy install: That is, the , partition with the bootloader was on , and it didn’t seem there was any corresponding partition on . The good news is that this indicated that I could probably just restore the required boot files to for Windows and be on my way. To do so, I used Hiren’s BootCD PE on a USB drive with Ventoy . Once in the Windows PE environment, we can restore the files with and in the command prompt. Now that we’ve assigned a letter, we can fix the files: where specifies the volume letter of the system partition, and specifies the firmware type ( copies all of them). At this point, I could once again boot from this drive and land in Windows. But, we could do even better! Having to use the BIOS boot menu is annoying: you typically have to spam an -key at startup, and if you miss your opportunity, need to restart again. It would be nice to be able to just boot to the same bootloader and select Windows, like in a traditional single-drive, dual-boot setup. Turns out that isn’t hard, since Omarchy uses Limine out of the box. In Linux, we can just edit the boot config. Then, I added the following entry after the Omarchy ones, and before the EFI fallback. With this, I then configured my BIOS to with Limine as the first boot option, and disabled the others. Now, it boots to Limine on startup, and my Windows drive is once again an easy option to select. Nice.

0 views
Luke Hsiao 2 months ago

Berkeley Mono Variable (TX-02) in Ghostty

Inspired by Michael Bommarito’s post , I’m just dropping some quick notes on getting Berkeley Mono Variable (TX-02) to work in Ghostty. Specifically, Berkeley Mono , released on 2024-12-31, running in Ghostty . Using the variable version of the font is highly convenient: it is very fast to change styles and tweak things until it is exactly how you like it, without having to iterate with installing static fonts. I suggest you read his post first for lots of nice context on fonts and their features. Then, the key bit of information I needed to get this working was the following. TX-02, the updated version of Berkeley Mono, has different OpenType features than the original. There is no documentation I could find on exactly what they mean, but via some trial an error, I’ve landed on the following config. Specifically, I found that and appear to change what the stylistic sets do (to different things than my comments). , , and don’t do anything that I noticed. So, effectively, it seems to me that the only two features you actually care about are your settings, and then whether you want ligatures with , and what style of / you want via stylistic sets. Another tip: if you have static versions of Berkeley Mono installed, I noticed that that sometimes breaks Ghostty from loading Berkeley Mono Variable. I’m unsure why, but I was able to resolve it by removing the static fonts, configuring things, and then putting them back.

0 views
Luke Hsiao 3 months ago

The youngest sibling advantage

I am the youngest child in my family. I’ve heard a lot of discussion around the stereotypical traits of the youngest child. In fact, many of these are so commonly echoed that they have their own name: youngest child syndrome . Sure, some of these arguably apply to me (certainly my older siblings would label me spoiled), and others do not. But, what I haven’t heard in many of these discussions is what I consider to be the biggest single advantage: life scouts . No, not like Boys Scouts of America “Life” scouts, like people scouting ahead for you in life. The youngest child often has older siblings they have observed keenly, maintained a strong and open rapport with, and with whom they have shared significant life experiences. They know them at a profound level. They then get to observe these older siblings blaze a variety of trails through life, years ahead of them. The youngest get to observe the decisions the older siblings make, often well aware of context, and then see the consequences of those decisions play out. Sometimes those consequences are positive, and sometimes they are not. Sometimes the outcome seems causal, and sometimes it seems that luck played a large role. Sometimes that whole decision-consequence cycle can happen well before a younger sibling might be faced with a similar decision. In many ways, this is like mentorship on an amplified level. Not mentorship in terms of career or school advice, but mentorship in life—hard earned advice and examples in real time, with real stakes, resulting in real impact. The advantage of having life scouts naturally follows. The youngest now has deeply detailed experience of highly trusted people to draw from when navigating the world ahead of them. As a kid, you already know the best parks or playgrounds nearby. You also know what areas of the neighborhood are dangerous. As a student, you’re confident in navigating the school system, and the trade-offs of different schedule choices. As an adult, you have gleaned some insight on dating and partner choices, and how those can affect directions in life. You have observed different fields of study or career choices, and how those areas affect stress, income, flexibility, and more. You have witnessed glimpses of different parenting styles and parenting choices. The examples are endless. Sure, not everything directly transfers, but I’ve found these “life scouts” to be priceless in my life. A shout-out to all the older siblings out there who pave paths and building organizational knowledge for those of us who come afterward. We appreciate you! As for me, I think benefiting from such mentorship (from siblings) is also why I value mentorship in general so highly. As the youngest sibling, I might not be able to provide powerful mentorship this particular way, but I still can hopefully pay it forward to nieces and nephews and other youth in my community.

0 views
Luke Hsiao 3 months ago

Comparing UTOPIA ISPs

I currently use UTOPIA for my fiber connection. Their model is that they charge for the infrastructure, and then they have many ISPs on top that provide competing internet services. As a snapshot comparison (primarily for my own notes), here’s a comparison of pricing for residential service, on the tier of 1Gbps download and upload (symmetric). This is the tier I’m currently on. At some point, I want to go through and learn more about their nuances. For example, XMission has an annoying trait of running their own firewall, which breaks websites occasionally. But, they also run their own datacenters and have some nice peering agreements that likely improve latency and performance. Here’s a UTOPIA-provided comparison sheet , too. There is some discrepancy in the pricing and the ISPs themselves, though.

0 views
Luke Hsiao 6 months ago

Variable fonts and italics across browsers

I’m a big fan of Atkinson Hyperlegible Next and Berkeley Mono (TX-02). It is my opinion that they both look great, unique, and provide valuable legibility features. I recently refactored this site to use the variable, web versions of these fonts. I was happy that I now had only a single definition, not a handful, and went on my way. (I had haphazardly picked up these parameters on the Internet somewhere.) Then, just recently, I realized that my italics were broken on this site for weeks! They worked on Chrome as I had it configured. They did not work on Firefox. I tried a few things. First, I tried duplicating the definition, but with . This made it work on Firefox, but broke Chrome. I then found there is a new way to specify italics for variable web fonts, specifically (assuming it is supported by the font): . In the case of Atkinson Hyperlegible Next, I could get my italics looking right on both Firefox and Chrome by adding the following CSS. But, this didn’t work for Berkeley Mono. I also tried things like using in my definitions and other little tweaks to no avail. Finally, after more experimentation, I was pleasantly surprised that I could get everything working just by simplifying . I dropped the (likely incorrect) attribute. No need for the class override, now, either. With that, I have italics , both for my normal font, and for my font that work on both Firefox and Chrome. All I needed to do was delete the right two lines.

0 views
Luke Hsiao 6 months ago

Performance gains of undervolting a T480s

I have been using a self-refurbished Thinkpad X230 for quite a while as a personal machine. I believe in the benefits of continuing to use old laptops [ 1 , 2 , 3 ]. However, recently, I’ve started to need to use a laptop to do presentations frequently, and the HDMI port on my X230 is not functioning fully, resulting in distorted colors and other distracting artifacts. I might try and repair that, someday. However, due to pressing need, I instead picked up a used T480s from a good friend, which had a working HDMI port. Of course, the first thing I did was install omakase-blue . Over the first couple days of use, I noticed that this thing ran hot . Sure, I have the version, but the fans were spinning up far more than I’d like, and CPU temps would frequently exceed 95 °C for bursts at a time. Naturally, I did a little digging. It turns out, Linux and the T480s have a longstanding problem! I don’t understand the problem well enough to explain it here. But, essentially, people were seeing throttling and temperature issues with these machines on Linux (but not Windows). To be clear, this issue was found on an old Linux kernel (4.15, I’m on 6.14). I do not know if this specific problem is affecting me. However, through this, I learned about a fun tool for undervolting a T480s: . Even if this issue was resolved in newer kernels, I imagined that some undervolting could still help my thermals and performance. So, I tried it. In addition, to give the attempt the best chance it had, I also replaced the thermal paste with fresh Duronaut . I was surprised to find a 12% improvement in single-core performance and a 24% improvement in multi-core on Geekbench 6! The laptop runs much cooler, and the fans spin up much less. It’s much more pleasant to use. I ultimately landed on the following undervolt for this machine. (Remember, each chip is different, you might not be able to use these values.) What a satisfying way to squeeze a little more performance out of a still-great laptop.

0 views
Luke Hsiao 8 months ago

Steel man arguments, or arguing intelligently

I’m a big fan of the idea of “steel man” argument. However, I’ve found that this term is far less widely known than its “straw man” counterpart. I’ve heard some people just call this “arguing intelligently”. Here are two good definitions if you’re unfamiliar with the idea. First, Wikipedia’s for the more abstract definition, and then Robin Sloan’s practical example. Wikipedia : A steel man argument (or steelmanning) is the opposite of a straw man argument. Steelmanning is the practice of applying the rhetorical principle of charity through addressing the strongest form of the other person’s argument, even if it is not the one they explicitly presented. Creating the strongest form of the opponent’s argument may involve removing flawed assumptions that could be easily refuted or developing the strongest points which counter one’s own position. Developing counters to steel man arguments may produce a stronger argument for one’s own position. Robin Sloan There are two debaters, Alice and Bob. Alice takes the podium, makes her argument. Then Bob takes her place, but before he can present his counter-argument, he must summarize Alice’s argument to her satisfaction — a demonstration of respect and good faith. Only when Alice agrees that Bob has got it right is he permitted to proceed with his own argument — and then, when he’s finished, Alice must summarize it to his satisfaction. The first time I saw one of these debates, it blew my mind. Or, as Stephen R. Covey put it: “ Seek first to understand, then to be understood ”. Imagine if the default mode of debate was like this. A tool for persuasion, consideration, exploration, and achieving consensus (or at least clearly understanding the shape of disagreement). Instead, culturally, we’re more used to debate as a stage for name-calling, politics, distraction, point-scoring, and drama. Next time you’re debating something, consider arguing more intelligently, and treating the other parties with that same human respect.

0 views
Luke Hsiao 8 months ago

Sharing intro cards

Those who know me know that I am fairly introverted. But, I am also someone who strongly values community, and thinks there are huge benefits to be had by building or connecting to one. A big part of building or integrating into communities is getting to know the people in them. Some people have a natural talent for this. Others have built that skill through many years of deliberate practice. There are also some people that use software to manage and track these relationships “personal CRM”-style (e.g., Monica , or really detailed notes in Google Contacts). I am currently none of these people. But, I would like to build the skill. One reason knowing people is valuable is because it helps facilitate connection. “Oh, I know is in that industry, let me connect you.” “The family has kids that line up with your kids age and go to Junior High, too.” “Oh used to live right around there, let’s ask them for advice.” These types of serendipitous connections can build strong bonds and strengthen a community, but you can only make them if you know enough. To that end, I think “intro cards” are an interesting idea. Imagine that when you moved in somewhere, or went to a new group meeting, or church event, or met with the other parents for your kid’s soccer team, that you could get a small physical card of pertinent information about these new people you met. In big social settings like that, where you’re meeting a lot of new people, it’s very easy (for me, anyway) to have forgotten the names of the people I just talked to. Now, instead imagine that throughout the event, you were exchanging intro cards, something like the following. During the event, you could focus completely on the current conversations, knowing you already have some notes provided to you to recall the previous ones. Is the concept so wild? In Japan, there is a whole interesting culture around exchanging business cards . In the US, we rarely do so. Japan recently went even further, making a whole trading card game for the middle-aged members of their small rural town, connecting the youth to older generations in a heartwarming way. Naturally, these intro cards might include personal information you probably wouldn’t put on the Internet, but yet might want to provide to people depending on the context. So, of course, you should tune the content to the purpose. You should also feel things out first, before you just go handing these to everyone. For example, in the context of introducing yourself to neighbors, maybe it is something like Bart’s above. If it’s meeting coworkers, maybe it highlights parts of the system you’re familiar with, or your favorite software or languages. If it’s a hobby group, maybe it highlights more about your specific niche interests. I’ve started trying this idea out in a few scenarios, to positive reception. To make it easy, just print these on 3“×5“ index cards at home. An example Typst document for it is included below.

0 views
Luke Hsiao 9 months ago

Teammates, not coworkers

I was talking with a friend a while back who had gone through some jobs they didn’t enjoy, and had now landed on a job they seemed to thoroughly enjoy. When I asked them about it, the key reason they provided for why this particular job seemed so much better was: “I have teammates, not coworkers.” That phrase has resonated with me since. What distinguishes a “teammate” from a “coworker” in a way that improves job satisfaction like it did for my friend? Here are some thoughts. I believe explicitly listing principles and values is incredibly valuable in all sorts of contexts . I particularly think that is true in the context of a company. Many , many companies do this , and know that it is a meaningful way to differentiate themselves to potential applicants as well as provide a guiding force for the business. Sometimes it is under different names, but the purpose is generally the same: broadcast their principles, values, and way of working to attract like-minded teammates. It also goes without saying that professing principles/values doesn’t stop a company from being evil (see Enron). Sometimes, values can come into tension with each other, and that is healthy. But, it’s hard to be a good teammate when there is not a large overlap in values. Instead, it will be a consistent source of friction. Fundamentally, I think this is the key point. Then, depending on what those shared values are, it’s easy to see some concrete examples. Here are some examples that I think are teammate behavior drawn from my personal values . Entropy in engineering shows up a lot of different ways. It could be the codebase (i.e., the software architecture, the abstractions, the tooling, etc.). It could be communication (i.e., messages that lack sufficient context, require unnecessary back-and-forth, etc.). It could be all sorts of other things (documentation, company policies, IT management, and more). I’d also classify complexity in general as a component of entropy, despite the fact that growing complexity is often fundamental to a developing product. I define complexity as APOSD does : “anything related to the structure of a software system that makes it hard to understand and modify the system”. This generally pragmatic definition also applies to things outside software. Entropy is the extra noise, disorder, confusion, etc. I’ve found that people I’d call teammates naturally reduce entropy (and strive to contain complexity) in their respective domains. Meanwhile, coworkers are often the source. Some examples: Teammates are the type of people that actively educate and build the collective skills of those they work with. They are the subject of those “Alice showed me how to”- or “I picked this up from Bob”-style comments. They are the ones who introduced you do that game-changing editor feature, or taught you about dotfiles, or helped you get up to speed and build a good mental model for that part of the codebase. They recommended that book that you read that changed how you thought about something. They are the ones you frequently have deep, meaningful conversations with. Teammates share because they want to. Teammates make the people around them more effective now, while also helping them grow and expand their potential in the future. Here’s another way I see this happen. Suppose there is a task that requires some custom effort. Someone probably had to write a little script or something to do the job, maybe had to deal with some edge cases. Now, you are handed essentially that same ticket and a pointer that “it’s just like last time”. If you have a teammate, you would go to that other ticket, and likely find everything you need. They probably even shared the snippet they used. If you have a coworker, you would go that other ticket, and likely find nothing except it being marked “Done”. Coworkers aren’t interested in sharing. That’s not their job. Sure, the company isn’t a family . It’s not meant to be. But, as DHH says, You don’t have to pretend to be a family to be courteous. Or kind. Or protective. All those values can be expressed even better in principles, policies, and, most importantly, actions. Teammates care about the team. Teammates break down silos and artificial divisions, resulting in increased unity. They are people you enjoy working with, and you can tell they genuinely care about you. Their pattern of care often extends into their other communities as well. You sincerely look forward to interactions with teammates. Coworkers don’t bother investing in relationships outside what impacts their core job. Interactions with coworkers might be laborious and taxing. This one might be controversial. I think teammates enjoy the craftsmanship of whatever craft they are engaged in. They are often the people that inspire others from their enthusiasm. Maybe they play for the love of the game. Maybe they play to win. They are the ones metaphorically early to practice and always hitting the gym. Their enthusiasm and corresponding work ethic is contagious. Coworkers are just here to get that cash and do other things. Indeed, I think it is also common for a person to be a great teammate by this measure in some contexts while simultaneously not being a great teammate in others. (Nikola Jokić, who I’d argue is a great teammate, is one prominent example of an exception here with the way he exemplifies team play but, in the off-season, couldn’t care less about basketball.) I’m sure I’ve missed a lot of examples here, but even so, it’s been a good source of personal reflection to think about how I myself can try and be a good teammate. I certainly am convinced that striving to be a good teammate, and having good teammates, leads to improved job satisfaction and team success. A coworker sends a bare hello , a teammate includes the context necessary to make asynchronous communication effective. A teammate opens that PR fixing those 6 typos in the source code comments. A coworker sends that message tagging a bunch of people to investigate a “super flaky test”, only to discover the issue is a real bug and the tests were not flaking at all after people context switch to help. They do not respect others time as much as their own. A teammate is willing to context switch to help. A coworker opens a PR with a bunch of code that “might be used in the future”, even though it’s not right now, increasing maintenance burden. A teammate deletes dead code. A coworker provides unhelpful commit messages like “fix stuff”, or has poorly organized commits, or general doesn’t explain the why. A teammate provides thorough context that often helps future debugging efforts. Teammates introduce tooling, frameworks, design patterns, etc. to help systematically reduce complexity. A teammate is the type of person that puts their shopping carts away, regardless of whether people are watching.

0 views
Luke Hsiao 9 months ago

How to connect MTP to a kids profile on a Fire tablet

This is mostly a note-to-self. I’m a father with a kid that is starting to get old enough to appreciate some screen time. To that end, we got a cheap Amazon Fire tablet (sidenote, it seems Amazon has a corner on this market). It was nice, we set up a kid’s profile, disabled the store, disabled calling, disabled the web browser, shared VLC (for personal media) and AnkiDroid (for educational flashcards). But, then I couldn’t figure out for the life of me how to get media onto the internal storage in a way that was visible to that kid profile! Here’s the trick: Step 3 in particular was not obvious to me. Log in to the kid profile. Bring down the settings menu by dragging down on the top. Press and hold the Bluetooth icon until a PIN prompt appears. Enter your pin. The “Connected devices” menu will open, where you can change the USB setting to File transfer. Now, the internal storage reflects this kid profile specifically.

0 views
Luke Hsiao 10 months ago

Oral histories are family treasures

A few years ago, my father passed away from cancer after many tough years of treatment. That was a tough time. Once it became clear that there likely were not many years left, around Thanksgiving and Christmas, I took a trip home with one particular project on my mind: conducting some oral history interviews, particularly with my dad. The artifacts from that project have proved to be treasures to me. The goals of this post are: (1) plant a seed of persuasion to you that this might be something you might find value in, and (2) share some tips I learned along the way. First, I want to recognize the valuable content that the UCLA Center for Oral History Research has put out. Much of my preparation was simply reading these pages. In fact, for the questions section, I am going to duplicate their page nearly verbatim, as an extra archive. Before that, I want to call out two things that I found particularly valuable before getting to the questions. First, audio quality matters. I mean it really matters. When I went into this project, my original intention was to just conduct interviews, and then I had a more ambitious goal of actually writing up a family history book. In fact, I even got a couple chapters in, in LaTeX and everything. But, once my father passed, I gained knew appreciation for the high quality audio itself. Sure, a book might be the more effective way of transmitting and documenting information for information’s sake. But there was so much value in hearing his voice. Hearing him tell his stories his way. Yes, you could do this with just a cell phone, and that would absolutely be better than nothing. But, if you have some time to do a little prep work, just spending a bit more time and money on getting equipment and learning how to use it brings the value of the audio to another level. The UCLA page suggests some gear. In my case, I went with a Motu M2 audio interface, along with a couple of relatively cheap dynamic XLR microphones, and it worked wonderfully. I recorded with a high bitrate and then distributed OPUS-encoded files to the family. Second, get a proper release form up front. Again UCLA provides and excellent example . Tune it to your needs. Even if this feels overkill, it sets a good mindset for the interviewee about how this might be used. In this section, I duplicate the UCLA Center for Oral History Research’s family history sample outline and questions nearly verbatim. But, I also have some suggestions on how to prepare that are likely different from a more generic process. Let’s start with the outline. 1.1 Parents and Family When and where were you born? Tell me about your parents or your family background Where was your family originally from? What did your parents do for a living? Did you contribute to the family income or help parents in their work in any way? What was your parents’ religious background? How was religion observed in your home? What were your parents’ political beliefs? What political organizations were they involved in? What other relatives did you have contact with growing up? What do you remember about your grandparents? What stories did you hear about earlier ancestors whom you never knew? How many children were in the family, and where were you in the line-up? Describe what your siblings were like. Who were you closest to? Describe the house you grew up in. Describe your room. What were your family’s economic circumstances? Do you remember any times when money was tight? Do you remember having to do without things you wanted or needed? What were your duties around the house as a child? What were the other children’s duties? How did duties break down by gender? When did you learn to cook and who taught you? Were there any special family foods or recipes? Do you still make any traditional family foods? What activities did the family do together? What did you do on Christmas? Thanksgiving? Birthdays? Other holidays? 1.2 Community You Grew Up In Describe the community you grew up in. Describe your neighborhood. Where did you shop? How far away were these shops and how did you get there? What’s the largest town or city you remember visiting when you were young? Can you describe your impressions of it? 1.3 Early Schooling What was school like for you? What did you like about it? What was hard about it for you? Who were your friends at school? Who were your favorite teachers? Do you remember teasing or bullying of you or anyone else? 1.4 Friends and Interests What did you do in your spare time? Who were your friends and what did you do when you got together? Did you have any hobbies? Favorite stories? Favorite games or make-believe? Favorite toys? What did you want to be when you grew up? 2 Teenage Years 2.1 Changes in Family How did your relationship with your parents change when you became a teenager? If you had conflict with them, what was it over? Did you have chores around the house? What were they? 2.2 School What were your favorite subjects? Particular interests? What were your least favorite subjects? Did you have any memorable teachers? Describe their teaching style. How did they influence you? What were the different groups at your school? Which did you belong to? How do you think you were perceived by others? Were you involved in any extracurricular activities? What were they? What were your plans when you finished school? Education? Work? What did your parents think of your plans? What did your friends think? What did your friends plan to do? Did the boys and girls in the family have different plans/expectations? 2.3 Work Did you have jobs during your teenage years? Doing what? Did you contribute to the family income? If not, how did you spend your money? 2.4 Social Life and Outside Interests Who were your friends? What did you do together? What individuals did you spend the most time with during this period? Was your group of friends single-sex, or did it include both boys and girls? At what age did you begin dating? What kinds of activities did you do on dates? Describe your first date. What was your parents’ advice/rules related to dating/contact with opposite sex? What were your peer group’s norms with regard to dating and relationships with the opposite sex? What were your hobbies/interests? What books did you read? What music did you listen to? What sports did you play? What crafts did you participate in? 3 Adulthood 3.1 Further Education 3.2 Work and Career 3.3 Marriage or Formation of Significant Relationship When and where did you meet? What drew you to them? When and how did you decide to move in together and/or marry? What was originally the most difficult for you about being married/being in a relationship? What was most satisfying? What advice would you give to someone today who was contemplating a serious relationship? 3.4 Children Describe the birth of your children. What were they each like when they were young? How have they changed or not changed? What were their relationships with each other and with you like when they were young? Now? What activities did the family do together? What family traditions did you try to establish? Does your family have any heirlooms or objects of sentimental value? What is their origin, and how have they been passed down? What was most satisfying to you about raising children? What was most difficult? What values did you try to raise your children with? How did you go about doing that? What forms of discipline did you use and why? 3.5 Ongoing Interests and Hobbies 4 Overview and Evaluation What has provided you the greatest satisfaction in life? How would you say the world has changed since you were young? Also, ask about historically significant events the family member lived through: I think you’ll agree with me that these are an impressive set of well-considered questions. But, here’s the key: customize . Before you do the interview, maybe in collaboration with other interested parties (e.g., other family members), go through and customize this for that person in particular. For example, asking about their memories about the US civil rights movement might be a pivotal point for some, and largely irrelevant for others. Drop questions that are irrelevant. Add questions you personally want to know. One particularly effective thing to do is to seed examples you can use in the interviews. Here are some examples. Consider question 1.2.1: “Describe the community you grew up in.” This is by all means a great question. But, if you already know something you (or your preparation team) are interested in, having those seeds will make for a better answer. You’ll see this technique used in celebrity interviews frequently. For example, you might as the question “Describe the community you grew up in.” Then, after they respond, if they didn’t touch on a point you’d like to dig into, just a little seed can nudge them the right direction: “Wasn’t there a giant tree you broke your hand on once?” If you have stories you’ve heard in the past you’d love to capture from the primary source in their voice, just a little spark like this often does the trick. “What did you do in your spare time? I remember you saying once you played a lot of snooker?” “How did your relationship with your parents change as you became a teenager? I remember Auntie X telling a story about how you ____ one time?” Finally, be sensitive to sensitive questions. Maybe you heard a story that painted some relative in a bad light. Is it worth recalling here? Does the interviewee want to immortalize this negative story with no anonymity and potentially no evidence? Provide a reminder that the goal of these is to preserve and distribute these stories and have the decency to offer alternative conversations. Conducting these interviews was a fond memory. I appreciated the recurring teasing about “all this unnecessary equipment”. I enjoyed the conversations—I cannot remember ever talking to my dad directly for hours about his life as I did during the course of those weeks. But as time has passed since his passing, the value of these recordings has only continued to grow. When and where were you born? Tell me about your parents or your family background Where was your family originally from? What did your parents do for a living? Did you contribute to the family income or help parents in their work in any way? What was your parents’ religious background? How was religion observed in your home? What were your parents’ political beliefs? What political organizations were they involved in? What other relatives did you have contact with growing up? What do you remember about your grandparents? What stories did you hear about earlier ancestors whom you never knew? How many children were in the family, and where were you in the line-up? Describe what your siblings were like. Who were you closest to? Describe the house you grew up in. Describe your room. What were your family’s economic circumstances? Do you remember any times when money was tight? Do you remember having to do without things you wanted or needed? What were your duties around the house as a child? What were the other children’s duties? How did duties break down by gender? When did you learn to cook and who taught you? Were there any special family foods or recipes? Do you still make any traditional family foods? What activities did the family do together? What did you do on Christmas? Thanksgiving? Birthdays? Other holidays? Describe the community you grew up in. Describe your neighborhood. Where did you shop? How far away were these shops and how did you get there? What’s the largest town or city you remember visiting when you were young? Can you describe your impressions of it? What was school like for you? What did you like about it? What was hard about it for you? Who were your friends at school? Who were your favorite teachers? Do you remember teasing or bullying of you or anyone else? What did you do in your spare time? Who were your friends and what did you do when you got together? Did you have any hobbies? Favorite stories? Favorite games or make-believe? Favorite toys? What did you want to be when you grew up? How did your relationship with your parents change when you became a teenager? If you had conflict with them, what was it over? Did you have chores around the house? What were they? What were your favorite subjects? Particular interests? What were your least favorite subjects? Did you have any memorable teachers? Describe their teaching style. How did they influence you? What were the different groups at your school? Which did you belong to? How do you think you were perceived by others? Were you involved in any extracurricular activities? What were they? What were your plans when you finished school? Education? Work? What did your parents think of your plans? What did your friends think? What did your friends plan to do? Did the boys and girls in the family have different plans/expectations? Did you have jobs during your teenage years? Doing what? Did you contribute to the family income? If not, how did you spend your money? Who were your friends? What did you do together? What individuals did you spend the most time with during this period? Was your group of friends single-sex, or did it include both boys and girls? At what age did you begin dating? What kinds of activities did you do on dates? Describe your first date. What was your parents’ advice/rules related to dating/contact with opposite sex? What were your peer group’s norms with regard to dating and relationships with the opposite sex? What were your hobbies/interests? What books did you read? What music did you listen to? What sports did you play? What crafts did you participate in? When and where did you meet? What drew you to them? When and how did you decide to move in together and/or marry? What was originally the most difficult for you about being married/being in a relationship? What was most satisfying? What advice would you give to someone today who was contemplating a serious relationship? Describe the birth of your children. What were they each like when they were young? How have they changed or not changed? What were their relationships with each other and with you like when they were young? Now? What activities did the family do together? What family traditions did you try to establish? Does your family have any heirlooms or objects of sentimental value? What is their origin, and how have they been passed down? What was most satisfying to you about raising children? What was most difficult? What values did you try to raise your children with? How did you go about doing that? What forms of discipline did you use and why? What has provided you the greatest satisfaction in life? How would you say the world has changed since you were young? Was your family affected by the Depression? Did you or anyone close to you serve in a war? What do you remember of that experience? Did you support or oppose the war in Vietnam? How did you express your political opinions? Did you participate in, or do you have any memories of any of the movements that came out of the 1950s, ’60s, and ’70s, such as the civil rights movement or the women’s liberation movement? If the family member belongs to a group that has traditionally been discriminated against: what were you told, both positive and negative, about your group inside your family? Outside? Did you experience discrimination? Who were your role models? If the family member is an immigrant or the child/grandchild of immigrants: what do you know of the country you or they came from? Why did you or they immigrate? How did you or they immigrate? What were some of your or their experiences and difficulties of beginning a life in a new country? Do you remember your first contact with such significant inventions as radio, television, or a computer? When did your family first buy these items?

0 views
Luke Hsiao 10 months ago

So you want to test some headphones

I’m no audiophile , but I do appreciate a nice pair of headphones. While there is objectivity when it comes to measuring how headphones sound (e.g., frequency response ), ultimately, I find judging headphones a highly subjective experience. For example, I fully agree with DankPods that the Grado signature sound profile is delightfully sparkly and a joy to listen to, despite its rather unconventional frequency response. When you judge some headphones, what do you listen to? The best answer is: the music you love and are familiar with. But if you want some suggestions, here’s a nice list that crosses many genres that I have largely taken from M. Brandon Lee’s list of songs he chose for listening to the undisputed best headphones in the world . These are not songs I listen to regularly (indeed, some I only heard of from Brandon), but they all give an opportunity to hear the headphones in a unique way. I suggest listening to these with eyes closed. Listen for new details, the sound of fingers on a fretboard, the background harmony, the timbre of the vocals, the textures of the objects producing sounds, etc. Imagine the setting it tries to place you in. Be present in the music. If you have suggestions I should add to the list, please let me know! Coldplay - Paradise Daft Punk - Giorgio by Moroder or anything else from this album, e.g., Get Lucky (feat. Pharrell Williams and Nile Rodgers) Electric Mantis - Rose City Hannah Parrott - Flight Jeff Buckley - Hallelujah Joe Hisaishi - Summer Olivia Rodrigo - Drivers License (for you, Nicholas) Radwimps - Grand Escape (feat. Toko Miura) TesseracT - Seven Names Walk Off The Earth - Farther We Go (A Capella) Yosi Horikawa - Bubbles YOASOBI - アイドル

0 views
Luke Hsiao 12 months ago

My favorite software in 2024

As an engineer, I’m always refining which tools are in my toolbox. Here’s a big list of software I enjoy using in 2024. There are big overlaps with my list in 2023 . One change I’ve made this year: I’m dropping all mentions of anything I don’t touch at least once in a month. So, please refer to 2023 for some honorable, but less regular, mentions. aerc This is my email client of choice. I tried , but the configuration was too complex for me. , on the other hand, is very simple to configure, and works great in the terminal. I’m an advocate for using plaintext email , and works great for using email for git patches . It lets me use my of choice, search and filtering works well, and it’s quick. Let me also call out a new discovery here: . This works far better than the largely unmaintained I was using previously. You don’t realize how useful synced shell history is until you try it. You should absolutely try it. Installed it on a whim, and have been delighted since. I’ve aliased to and never looked back. The syntax highlighting, the line numbers, the git integration, the paging, it all just makes it nice to use. This is my favorite coding font. Yes, it was worth the $75! I used to use Iosevka , and I still find myself enjoying the slenderness of it when it’s useful. is a better (and ). I originally thought I wouldn’t need more than , until I tried to run it on a massive server with over 150 cores. you need to configure differently to see anything at all (dropping all the CPU bars), and it is slow . handles it just fine out of the box. The filtering on the processes widget is very convenient. The ability to see all the other stuff like temps, GPU memory usage, network utilization, disk utilization, those are all cherries on top. I’ll also call out that btop is also very fun, but I find bottom more useful. is a human-friendly alternative to and (sometimes) . I used to use for most of this type of task, but choose just makes it easier. It makes it easy to chop out columns I want while piping things around. This is a new addition. In general, I’m a big fan of “declarative diagraming” , and D2 is the new one on the block (vs PlantUML , MermaidJS , GraphViz , etc.) So far, I love the syntax and functionality. If I’m drawing up something quick that doesn’t warrant something like , I’ve been reaching for D2 first and excalidraw second. Their TALA layout engine is proprietary, but looking quite nice. is the best syntax-highlighting pager for git, diff, and grep output I’ve seen. I used to used , but since switching to , I haven’t looked back. This makes the experience of using git in the terminal much improved. I also have my eye on . is the another key tool I use side-by-side with . It is a structural diff tool that understand syntax . This means that many times, it is a much more succinct diff for files. I have this aliased in as well, and often use both and when looking at diffs. This is like , but better. It’s faster, and its visually nicer. This is my go-to way for figuring out where my disk space is being used. This is a replacement for that is just better. Similar to , after aliasing to , I haven’t looked back. is a replacement for . Similar to and , this is another rust-based tool that feels more intuitive and does the job better. Fish has been a great shell. I just used plain bash before this. I switched a couple of years ago, and while I don’t think there has been any particularly large “killer feature” for me, I have had no reason to switch to anything else since. The UI niceities (e.g., autosuggestions, tab completions, syntax highlighting, 24-bit color) all make the terminal experience pleasant. It’s also being slowly rewritten in rust . I’m interested in trying at some point soon, but I haven’t jumped in yet. When it comes to taking screenshots, Flameshot is my favorite. Easy to adjust, annotate (i.e., arrows, boxes, text, etc.), and save to clipboard, file, or imgur. is a command-line fuzzy finder that is incredible software. For friends who are new to spending time in the terminal, this is one of the first things I try to persuade them to install. It is worth it for alone. is my favorite version control software. Yes, that might be because it’s pretty much ubiquitous, and I’ve spent the time to get over the learning curve. It’s a fantastic tool. If you haven’t leveraged aliases ( here are mine ), then I hope reading this is a plug to go enjoy those. Since it’s git-related, I’ll also mention I’m a strong proponent of conventional commits , and using useful git trailers like they do for git itself and Linux. While we’re all used to the PR/MR type of workflow, if you haven’t experienced working with git the truly distributed way (via git-send-email ) its also worth trying. Otherwise, new software like pijul looks interesting, but I haven’t tried it personally. And, there are plenty of insightful opinions on what comes after git . This is my favorite find of the year. This fits exactly into my normal git workflow, and it’s algorithm is simple and effective. If you are used to making commits yourself, definitely try this out! If you’re following conventional commits , then is a fantastic tool for automatically generating useful changelogs. I use this in the vast majority of my repositories. This is a small tool that clones a git repository to a standard location, organized by domain name and path. I used to just have a directory full of random repos. At one point, I tried to organize these better (e.g., “personal”, “forks”, etc.), but it didn’t work well. Now, I just use and stick with that structure. “Ping, but with a graph.” That’s an accurate description, but don’t underestimate the niceness of a graph. It also has features like graphing multiple hosts at the same time, or graphing execution times of commands. Similar to , , , , if you have , you really don’t need to go to anymore. I’m embarrassed to say, but I didn’t really learn how to use until 2017. But, that was such a positive experience that I’ve been on modal editors since. I went from , to , and then, most recently, to . Going from electron-based editors to was a big jump. Going from to these others was just incremental. I had developed a very custom experience with plugins and all sorts of customizations. That, surprisingly, is part of the reason I’ve enjoyed so much: I use it pretty much stock. It’s got all the right basics built-in (LSP, file pickers, tree-sitter, etc.) such that I don’t need to customize it much. If you’re interested in experimenting with a new editor, I highly recommend helix. is an easy way to test HTTP requests with plain text. Since it can chain requests, capture values, etc., I actually often use it to “script” some request chains for testing purposes. I haven’t used this extensively, but so far, it seems very useful. is the best command-line benchmarking tool around. It should be the standard, in my opinion. If you ever want to benchmark how long a particular command-line command takes in a robust way, look no further. is a clone of the ubiquitous JSON processing tool. But, it is more correct and faster. As long as you aren’t doing crazy stuff with , might be an easy alias to make for some small wins. is a command-line JSON viewer. If you’re viewing JSON files with some combination of (or ), , , etc., then might be just what you’re looking for. It makes it easy to quickly peruse a JSON file and espand/collapse objects and arrays. is a versatile command runner that takes inspiration from , but without the baggage. This is a new entry on this list, and not one I have used as extensively, but so far, it seems nice. There are many situations where I have a with a bunch of targets because I’m just trying to use as a command runner. Well, now I have a nice command runner. There are several repositories I’ve worked with with a folder that could just be absorbed into a . Linear has become my team ticket/issue tracker of choice. Unlike some of its competitors, it is wicked fast, and I greatly appreciate it. That’s really it’s key feature. It has everything you’d expect, and then it adds great keyboard shortcuts for power users. The web is great, but it is unfortunate when you come across broken links. is a great way to help prevent that (they even have a GitHub Action ). It’s incredibly fast. I use it to check most of my repositories for dead links, as well as my blogs. I often used mdBook for documentation sites, but the lack of the inline table of contents, and the need for awkward plugins for things like admonish and mermaid was annoying. I’ve since switch mostly to Material for MkDocs and have been blown away by the quality of the framework. It’s got just about everything you’d want built in. All that said, I’ve got my eye on Astro Starlight and hope to try it out in 2025. While we’re talking about documentation, I’ll mention that I’m a strong proponent of the Diátaxis documentation system . If you’re wondering how you should organize your documentation, please consider it! The mobile shell that allows roaming, supports intermittent connectivity, and provides intelligent local echo. A recent release also brought true color support, which was the only thing that bothered me before. 99% of the time I say I’m “ssh”-ing, I’m actually just using . The ability to start a session, get a session all set up, close my laptop, go somewhere else, open it and just pick up where I was is too good to ignore. This is an example of software that is pretty much “complete”. Lack of activity on the repository shouldn’t scare you one bit, its because it has a rock solid history and does what it sets out to do. is the best media player I know of. I prefer this to VLC or others. It “just works” and is extremely minimal and performant. It’s integration with (or better yet, ) means I often just play web videos (even YouTube) via . Mumble is an open-source, low-latency, high-quality voice chatroom software. If you’ve used things like Ventrilo or Teamspeak in the past, you’ll have a good sense of Mumble. I’ve written about Mumble before , but it is my favorite implementation of this type of software. It is extremely lightweight, easy to self-host, and noticeably low-latency. Newsboat is a TUI RSS/Atom feed reader. I’ve used things like Inoreader and Miniflux in the past, but ultimately settled on . It’s simple configuration, local, and integrates nicely with my terminal-based usage patterns. is a very simple password store that follows Unix philosophy . I use a Yubikey for GPG, so means I don’t need a master password, I just need my security keys (see ’s guide ). I don’t miss having a password manager app on my mobile phone, so on desktop, this has served me well. I’m a big fan of its simplicity, and the fact that my passwords are just flat files I can version in a repo. is a command-line tool for indexing, slicing, analyzing, sampling, splitting, and joining CSV files. If you have a big CSV file and want to poke at it, do it with ! I used to use , but this is largely unmaintained for now. This is on steroids. Stop using and start using and you’ll never go back. It is significantly faster, and has a bunch of great features (e.g., searching file types, regex, automatic filtering, etc.). It is often thought of as the gold standard for excellent Rust code. is an intuitive rust rewrite of . Much like the other tools in this list (e.g., , , etc.) it is just a better option in most cases. I frequently use it in combination with to find and replace across a project directory. This is a great little tool to throw at the end of your pipe if you have long-running tasks and are like me and what to know when the last thing was printed. is the best live terminal sharing application I’ve ever used. I used to reach for things like for this, but it’s more constraining (e.g., I want to still use zellij). It also does not look as nice. has a level of polish no other tool I’ve tried in this space has had. This is by go-to tool for pair programming. They also just released the killer feature of read-only sharing , which makes this extremely handy in a whole slew of scenarios. This largely solved the screen sharing problem you might have if you use Slack or similar, but have an ultrawide monitor and your coworkers do not. With , the latency is impressively low and the text will be crystal clear. In a screen share, you have a compressed mess. I started using about the same time I started using . It’s a fun, fast, extremely customizable prompt with nice defaults. I’ve enjoyed it enough that I just haven’t stopped using it since first adding it to try. If you’re the type that has some line in your to know what git branch your on, you might enjoy starship as well. has replaced for me now that I’m on Wayland. It maintains everything I like about i3. On macOS, I’m using Aerospace , but it just isn’t the same. Thanks to wireguard , tailscale makes private mesh networking stupid easy. It’s my go-to tool when it comes to sharing things on a private network (e.g., self-hosted stuff with my family, ssh-ing into my desktop when out and about, etc.). It’s performant, well documented, and pretty much just works and gets out of your way. is the best way to get statistics around counting code in a repository. It shows you the total number of files and total lines within those files broken down by code, comments, blanks, and organized by language. It seems both faster and more accurate than tools like cloc , sloccount , etc. There are other great blogs posts about code counters . is a very handy spellchecker that seems to work in a code context better than other things I’ve tried. They have a CLI, as well as an LSP. It’s worth checking out! I usually have a config like this: simply runs a command when files in the current directory change (and it’s awesome). Made my the same folks who make cargo watch , this is a general purpose tool that can make your development loop feel faster when immediately starting long processes (linting, tests, etc.) immediately in response to code changes. Oftentimes, the checks/build/tests are finished by the time I’m ready to craft my commit. Definitely worth trying. If I’m making a dead-simple webpage (e.g., not complex enough to pull out a static site generator), my go to way to make it look nice is . This one stylesheet, one line in the is all you need to a nice-looking, responsive theme. has collected a large list of classless css themes/frameworks, if you want to check out others. This year, I finally learned about Fedora’s Atomic Desktops , as well as Universal Blue ’s images on top. These are an interesting paradigm shift, and pretty appealing as a Linux workstation. I’ve made the switch, and also released my own omakase-blue customization of it as a one-line installer. This is my favorite terminal emulator. There are a few key features I enjoy: speed (it’s GPU-accelerated), ligatures (this is why I switched from Alacritty ), easy configuration via file, clever hyperlinks , and quick select mode . Hyperlinks are easy to customize for your issue tracker (so you can open your tickets directly), and quick select mode makes grabbing hashes from in a separate pane a breeze. Highly recommended. is very similar to HTTPie . While I haven’t used the latter, I’m a big fan of over . The interface just seems more intuitive and friendly. And, it still has a flag so I can get a curl command in case I need to share it with a teammate. I used to use Mint, but when they shut down, I migrated to YNAB. I wanted to be more hands on, more intentional, and more aware of my spending, and YNAB seems to be a great tool for that job. I spend the vast majority of my time every day inside a session. I’m a fairly basic user, but the terminal multiplexing, scrollback buffer/search, ability to have multiple sessions and attach/detach is all I really need. and are a perfect combo. I like the visuals and UX enough to have had this replace . For non-documentation sites, my favorite static site generator is Zola. The template engine is great, and its fairly simple and easy to grok how themes work and can be modified. I use it for this site, as well as several others I’ve made. There are more discoveries this year than I would’ve anticipated!

0 views
Luke Hsiao 1 years ago

Omakase Blue: an omakase developer setup for Wayblue Sway

Update I ran into two pain points with that have been annoying enough for me to start experimenting with other solutions. First, I was finding that many things I use regularly require layering. Tailscale, Mullvad, Wireshark, etc. Wireshark in particular I could not get working correctly after a fair amount of effort, which was particularly frustrating as I reached for it to debug a pressing issue in my network. Second, docker in docker is clunky. My approach was to have a single, tailored distrobox that I essentially lived in. I did so with my own image, and using systemd quadlets . However, when it came to building images for dev purposes within this distrobox, things didn’t work out of the box. Presumably, there are ways to get this working . But again, my attempts were all unsuccessful, and it was becoming a time sink for something I want to “just work”. I still think Atomic Fedora is a very interesting idea for the reasons above, but for my own dev machine, I’ve returned to more traditional Linux. Now, I’m experimenting with Omarchy , along with my dotfiles to set up my preferences on top. I don’t expect this to be as stable as wayblue, but I do think rolling releases will give me much of what I’m looking for. In the past few months, I’ve come across two interesting and impressive projects. First, Omakub , an omakase developer setup for Ubuntu 24.04+ by DHH , whom I greatly respect. Second, Project Bluefin , an opinionated Linux workstation built on atomic Fedora images ( Fedora Silverblue , specifically). I couldn’t help but see this as an opportunity to learn more about immutable operating systems and spin up my own version. https://github.com/lukehsiao/omakase-blue In a nutshell, and completely repeated from the many landing pages of these immutable OS versions, workstations based on atomic Fedora images are interesting for a few core reasons. These three properties in a Linux desktop provide an opportunity to get some of the best of both worlds: the reliability and ease of use of a Chromebook, with the power of a Linux desktop. Put another way, if any of you are like me and often play the role of family IT support, you would likely agree that the best OS for the non-technical, aging user and the best OS for me, the developer, are almost certainly very different. However, these universal blue images are, in many ways, making a unique argument that the answer could be the same! In fact, it seems to me that the update model is uniquely user-friendly. In macOS, major updates take literal hours. Same with Windows. Typical Linux is faster, but things might break, and you might end up cleaning things up yourself. Here, you just don’t need to think about it—it will happen, like a Chromebook. I had never used any of these before, so I was eager to give them a try. In particular, I’m not a fan of Gnome on old laptops—it’s too slow. But, along this exact vein, it turns out there is a community-built version for Sway: https://github.com/wayblueorg/wayblue Among developers, we are used to seeing people’s personalized dotfile repositories , often managed with something like . It’s much rarer to see someone produce an incredibly thoughtful, polished one-line-installable script that takes a freshly installed OS and turns it into a complete dev-ready workstation. Omakub is just that. It turns a fresh Ubuntu installation into a fully configured, beautiful, and modern web development system by running a single command. In fact, Omakub is what DHH uses as the default starting point for his companies, now that they have moved from macOS to Linux . The code is in pure Bash scripts, wonderfully organized, with a lovely manual . It is a prime example of craftsmanship. DHH had a problem, he solved it, and it was done . With that context in mind, let me introduce Omakase Blue. turns a fresh Wayblue Sway installation into a fully configured development system by running a single command. No need to write bespoke configs just to get started or catch up on the latest command-line tools. It includes a highly curated set of applications and tools that I have discovered, tested, and found to be highly useful from reading blogs, news aggregators, etc. In addition, it includes default dotfile configurations for most of these tools that feel coherent. It is a codification of the toolbox I typically use to work. Nothing here is unique, and in fact, I’m highly confident that (1) there are many other ways to do things and (2) many of those other ways are in fact even better than what I’ve done here (and I would love to know about it, send tips my way!). However, it is tailored and appreciated by me. For those unfamiliar with Bluefin (like I was), here are some more details I hope provide a useful mental model for this setup. Bluefin’s developer mode encourages the following pattern: I break from this pattern in a few ways. First, I don’t like devcontainers. Not on principle, but because Helix , my editor of choice, doesn’t integrate with them, so I’ve never used them in the past. Second, I like to be on the bleeding edge for many CLI applications. For example, for those written in Rust, I like to build them from source and update via cargo-update . Third, I don’t ever have a need for many pet containers running a mishmash of distributions. I just want a familiar dev terminal, even though I’m using an immutable OS. Furthermore, I want to fully embrace the idea of an auto-updating foundation of software. So rather than a “pet container” that you essentially need to set up just like a normal desktop, I use podman quadlets to deploy an ephemeral toolbox container that is built on an image I also control and refine to include everything I want in it. This is a tradeoff: if I want something else in my containerized dev environment, I need to add it to the base image because if I just install it, it would disappear next update. But, if I do, I know it will be there and auto-updating forever. Users of should likely fork and create their own personalized toolboxes for this reason. In the end, here’s how it looks. How works is it first installs terminal-related tooling. It does so using on the host, and then setting up the omakase-toolbox ephemeral image (again, users are encouraged to fork and make their own). That image is already customized with a variety of tooling simply installed with , which is consequently only accessible within the container (as indicated by the blue). Then, for a bunch of useful CLIs, we build from source (e.g., using ) from within the toolbox (which has all the necessary dev libraries, unlike the host). These binaries typically end up in the home directory, consequently, are accessible to both host and container. Then, we install and configure the desktop apps (e.g., web browsers, image editors, PDF readers, etc.) Finally, we set up applications that are useful. In particular, we set up two shortcuts, one that runs on the host, and one that automatically opens a shell in the toolbox. I prefer WezTerm to the built-in ptyxis since it is more full-featured (e.g., ligatures, better performance, etc.). Finally, we do allow the container to execute commands on the host automatically if the command is not found in the container , giving access to things like or . is a set of scripts which sets up an omakase developer workflow from a fresh wayblue sway installation. In addition to specific tooling, along with their configuration defaults, we set up an ephemeral Distrobox container. My workflow is essentially that only GUIs are used on the host, and the rest of my time is spent inside the container. With this setup, I avoid the pitfall of feeling like I need to set up multiple computers (i.e., the host + whatever containers I am using). Instead, I use this atomic OS almost the same as I would any other. Since the terminal directly launches the container, I almost don’t notice I’m in a container at all. Reliability : Each version is updated for approximately 13 months, and each update takes effect on your next reboot, keeping your system consistent. You can even keep working while the updates are being applied! Atomic : The whole system is updated in one go, and an update will not apply if anything goes wrong, meaning you will always have a working computer. Safe : A previous version of your system is always kept around, just in case. If you need to go back in time, you can! Development done in devcontainers Command-line applications installed using Homebrew GUI applications installed via Flatpak Other things being done in Distroboxes

0 views
Luke Hsiao 1 years ago

Writing a mission, principles, and values for your family

Have you considered explicitly writing out the mission, principles, and values for your family? About a year ago, my wife and I had some big changes in life: a young child, living in a new state, planting some roots. It seemed like an apropos time to make a declaration of sorts of our family mission, principles, and values so that we could point back to the document, as both it and our family evolve over time. Since then, it has paid dividends. It is shocking how often we have referenced, and found grounding direction in that document. Its statements comprise the emotional, moral, ethical, and spiritual core of our family. In this post, I want to share them with you and reflect on some stories we’ve experienced since. Our mission, principles, and values are both blatantly and reverently modelled after those set by Bryan Cantrill and his company, Oxide , with tweaks to make them more family-relevant. Still, we contemplated and ultimately decided to include each with great care and intention. “Kick butt, have fun, don’t cheat, and find happiness together.” We believe in working hard and achieving excellence. We believe that our family journey is most fulfilling when it is fun, and that humor is essential for humility in good times and endurance in the hard ones. We believe in playing by the rules in both letter and spirit. If we don’t like the rules, we work openly and collaboratively to improve them. We believe the family unit cannot experience its full measure of happiness unless each constituent is happy and thriving. This means we exercise utmost transparency with our own concerns and deep empathy for another’s struggles. Principles are fundamental, universal truths that transcend time, geography, culture, and context. These are not aspirations, they are constraints; we expect them to be the marrow of our family and adhered to under all conditions. Principles are meaningless without the integrity to uphold them; we view our integrity as our single-most important principle. We do not sacrifice our principles for expediency or comfort. We seek and tell the truth, even where those truths are painful or inconvenient. We abide by the spirit of the truth, not merely its letter; we do not hide falsehoods in language that is technically true or otherwise misleading. We treat others with dignity, be they family, stranger, community, or competitor. Unlike principles, values indicate relative importance: they are objectives rather than constraints, and can come into tension with one another. Indeed, many of these values can become pathological when taken to an illogical extreme; absolute adherence to a particular value should never trump prudence. We believe in being forthright, even when that’s difficult. We avoid euphemism or otherwise cloaking our opinions or experience. We respect those who speak candidly, even if we disagree with what they are saying. We are bold, willing to do things even if they are unconventional, difficult, scary, or otherwise unproven. We are not, however, foolhardy: where we are contrarian, it comes not from mere desire to take a less traveled path, but from a deep and well-informed conviction. We are lifetime learners, unafraid of learning something new—be it an intimidating new language, a perplexing puzzle, or a novel technology. We believe the best results come from combining different perspectives and uniting them with shared values and mission. We believe in and encourage diversity on any axis that remains consistent with our mission, principles, and values. To find happiness together effectively, we must be able to see the world through the eyes of others. Empathy doesn’t merely inform our behavior, it guides our interactions with our family and community: we treat others as we ourselves would like to be treated. While living life is serious business, we don’t take ourselves too seriously. We enjoy the company of our family, and cannot imagine a day without laughing. While our lives are often filled with figuring out why things will fail, we nonetheless retain a deep and fundamental belief that better things are possible. We believe in the words of the late mathematician Piet Hein: “problems worthy of attack prove their worth by fighting back.” We persist even when problems are fighting back, pushing through the disappointment and setbacks endemic to our environment and our chosen domains. We feel a duty to things larger than ourselves. We don’t merely fulfill our obligations, but actively seek ways we can help. We balance our professional responsibilities with our personal and familial ones, and we honor those who do the same. We are disciplined and thorough in our approach to problems. We insist on getting at the root of things, and are unsatisfied to merely address their symptoms. We are intensely team-oriented people: we draw strength and inspiration from each other and our community. We like to collaborate, and believe that our best work comes when we work not merely together but for one another. We believe in spending wisely, seeking to make our finite resources last as long as possible, while still making the necessary investments to achieve our mission. Our shared thriftiness allows us to empower ourselves to make the right spending decisions. We believe that secrets are often corrosive—and that our family operates most effectively when we are aware of broader context. We err on the side of transparency and communication: every family member should feel that there is a standing invitation to discuss and collaborate on any issues. At the same time, we are respectful of privacy: personal issues should remain private. We have finite resources and limited time with which to achieve our mission; we must be focused in our approach however immense the task at hand. Urgency should not be conflated with pace; it is important to move deliberately rather than hastily. While we must naturally specialize, our mission also demands that any of us may need to adapt or apply ourselves in a new way—and indeed, that many of us will be doing this much of the time. We made a poster of this in our home. Here’s the Typst source in case you want to tweak it for yourself. I feel motivated and inspired by these statements. We initially set up this document with the thought that “in the future”, we wanted our children to be able to point to this as we resolved disagreements (e.g., “Dad, can we go to the Museum this weekend if I finished my homework. I’m showing responsibility, and it would contribute to curiosity!”). Sure, while we still hope this document comes in to play in the future, it is astonishing how often it has come into play for just me and my wife now . There have been times at 3am, when we were both up and frustrated and helping the baby where a reminder like “Teamwork, we’re on the same team”, or “problems worthy of attack prove their worth by fighting back”, soothed tension between us or bolstered our resolve. When we had our 10-year wedding anniversary, and reflected on the past decade, it was shocking how frequently references to this document appeared for both of us. It echoed things we admired about each other, our relationship, and our experiences. There have been times when friends tell us about some scenario they are dealing with and ask what they should do. For us, the answer is often surprisingly clear just based on our principles and values. In fact, in some cases, it’s been an effective line of thought to ask them to enumerate some of theirs, and then ask them what action would best align with their principles and values. We’ve all heard cliché lines like, “in this family, we …”, followed by some statement (in the worst cases, often pulled from thin air in the heat of a disagreement). With a document like this, I hope it’s very clear that in this family, we have integrity, honesty, and treat people with decency. Furthermore, we have a lot of things we value, and recognize that while they are objectives, not constraints, they point us in the direction we would like to go.

0 views
Luke Hsiao 1 years ago

On the usefulness of knots

How is your knowledge of knots? Despite being an Eagle Scout, I would have to answer: very poor. I’m confident that just about everyone knows the Overhand knot, the Reef knot (or Square knot), a shoelace knot (or more ), and a Slip knot. As a Boy Scout, I could also throw a Bowline into that mix. And yet, if I was tasked to tie a knot outside the context of a shoe, a garbage bag, or a bread bag, that needed to be secure and reliable, my confidence would plummet. I suspect that outside of a few professions/hobbies like rock climbing or sailing, which come with an outsized knowledge of knots, many people would be similar to me. For example, here are a few common scenarios I’ve found myself in. Would you have a good answer? I need to attach a cord/string/rope to something with a small circumference (e.g., a bar, a bag opening, a bundle of cables, a chicken drumstick bone), as securely as possible. Maybe if I had a zip tie, I’d use that, but I only have my cord/string/rope. What knot would you use? I have two pieces of cord/string/rope and need to attach them together very securely. Maybe to make a longer rope. What knot would you use? I need to cinch down something, say, on a truck bed or maybe a tent strap. But, I ran out of cinching hardware. I only have rope. What knot would you use? I wouldn’t be surprised if many people reached for a Reef knot in all of these instances, simply because that’s the only one that came to mind. Me too, until I spent $6 on a simple knots reference application ( Knots 3D ). Why an app? Offline reference is important, because half the time I actually want to look at this, I’m somewhere remote with no internet. Now, I’d recommend a Constrictor knot for scenario (1), or a Double Constrictor if you’re getting really serious. Or, depending on the exact case, perhaps a Woodland Zip-tie Knot or Canadian Jam Knot . I’d use a Zeppelin bend for (2). I’d use an Adjustable Grip hitch , or a Trucker’s hitch for (3), depending on the exact scenario. In fact, even knots I believed to be very secure, like the Bowline, have better variants. For example, anytime you want a Bowline, you’re better off with Scott’s Locked Bowline instead, which inhibits the knot from shaking loose. Frankly, there are a bunch of cool loops you should check out, like the double dragon knot or a Kalmyk Loop . As a programmer, learning these knots feels a lot like discovering some mature, well-established CLI tool that solves your particular problem very effectively. With a knots reference handy, you can chuck a roll of paracord (for its absurd versatility and strength) in your bag or car, and you’d be surprised how many times you can solve a problem with a good knot. I need to attach a cord/string/rope to something with a small circumference (e.g., a bar, a bag opening, a bundle of cables, a chicken drumstick bone), as securely as possible. Maybe if I had a zip tie, I’d use that, but I only have my cord/string/rope. What knot would you use? I have two pieces of cord/string/rope and need to attach them together very securely. Maybe to make a longer rope. What knot would you use? I need to cinch down something, say, on a truck bed or maybe a tent strap. But, I ran out of cinching hardware. I only have rope. What knot would you use?

0 views