Oct 2025
On Secure by Design π
I was listening to the podcast SE Radio 684: Dan Bergh Johnsson and Daniel Deogun on Secure By Design. The episode describes a practice that also aligns with what the software engineering discourse has been agreeing about in the past decade or two:
- The 5 level of validation: we do the simplest, most broadstroke validations first on the input data. As we move forward & more confident about the validity of the input, we perform the more expensive validations, and finally semantic validation: how correct the data is in the context of the application
- Parse, don’t just validate: the podcast episode look into the concept of domain object, which is constructed through a process of validating input data
- Repave: rotate server instance/container/pods periodically. This will periodically flush what an attacker managed to setup on your instances. Also will prove that your architecture is reproducible & easy to scale.
Listening to Podcast π
I’m looking to start learning French seriously. One of the recommendation to improve my listening skill is to listen to Podcasts and Audiobooks. So naturally I find a selfhosted platform to manage podcasts & audiobooks to run it on my very own Raspberry Pi home server. The solution I found was Audiobookshelf. Simple, no frill, no fuss; just add postcast entries to my feed and the system downloads the episodes automatically.
But then the problem of limited storage on my little RPi means I cannot download all the podcasts I intended to read, especially when Audiobookshelf is modelled to work as a central library of all audiobooks & podcast, while I was looking for something that downloads only to my phone or laptop.
I guess I’ll stick to Apple Podcast for listening to podcasts, while I’ll see to use Audiobookshelf to maintain the audiobooks library. In case I need to move to another podcast listening client, there is still a way to export my subscriptions from Apple Podcast.
The story of the port numbers π
What does some of the common applications’ default port numbers mean:
- 3000: a random number picked by the ExpressJS example. This in turns, influenced a whole generation of JS developer, both frontend & backend.
- 5173: the default port of the new Vite bundler, replacing Webpack. This is the Leetspeak of translation of Vite, (5 gets translated to V in Roman numeral)
- 8080: pioneered by the Java people. Want to start listening to HTTP on port 80? Too bad, you need superuser permission. But 8080? That works just fine.
- 11434: Also leetspeak. If you rotate the number 3 90 degree counter clockwise, you will get a letter M, and the number spells Llama. Used by Ollama
Muting my microphone quickly and reliably π
The criteria for this is simple:
- A shortcut that mute/unmute my microphone
- With visual indicator
I tried MicDrop and immediately fell in love with it. So quickly that I just shed 5 bucks to get the full version right away
I have the whole range of F keys that I mostly don’t really use. So I just bind the F5 key β which has the mic icon on it to enable the dictation feature β to toggle the microphone.
The coolest pair of config of MicDrop is push-to-talk & press twice to change from push-to-talk to push-to-mute. So normally I would set it on mute. If I just want to speak something quickly, I’ll push to talk. But if I want to stay unmuted for a while to present something, I tap the button twice.
UX-wise, this app is very polished. Simple, no-nonsense. Enough visual cue to let me know what is going on.
Too cool for just 5 bucks.
Don’t use Claude Code ACP integration in Zed Editor for production code at the moment π
I was very giddy when my DevContainer setup with Claude Code installed booted up, connected to Zed editor and chug along very beautifully. That is until I saw it read my .env file where I put some of my app credentials. The whole file in plaintext just got sent to Anthropic’s server.
After 10 minutes of cussing my stupidity of putting real credentials in front of a LLM with no protection and rotate all the password & keys, I started looking for way to make Claude ignore those files.
Anthropic’s page told me to deny Read(/.env) in the project’s .claude/settings.json file. That’s what I did. I put it in the .claude/settings.json file
{
"permissions": {
"deny": ["Read(/.env)"]
}
}
But when I asked Claude Code in Zed to read me the content of my fake .env file, it gladly complied, no matter how I tried to configure it.
However, using Claude Code in the terminal works just fine.
After trawling through the codebase of
Claude Code integration with Zed, using a protocol named
Agent Client Protocol
1
1
Also invented by Zed.
, I found the answer: The protocol short out several Claude Code toolcalls and override it with their implementations, so it can integrate closely with the editor & provide cool UX flows. The Read request doesn’t reach the Claude Code app, but instead handled by Zed directly and that’s why it doesn’t honor the permissions we define.
The problem is not with the integration bridge, but with the Agent Client Protocol itself. As of this moment, the spec define if the agent request a file, the client (editor) is expected to comply.
I think that what Zed is doing is pretty cool, and the push for ACP 2 2 Confusingly, there is another LLM related protocol with the name ACP β Agent Communication Protocol β launched by IBM. About time either team changes their name. can be a good move with improving model support for every other IDE and Text Editor. However, things are pretty bare-bone, unpolished now as it is still in Beta. Seems like security is not something that the protocol designer are truly focusing on. Let’s keep it away from our sensitive codebase for the moment.
Finding myself a True Wireless earbud for conference call π
I took calls quite a lot. About 3-4hrs during my work day are spent on call, even when I speak for less than 5 minutes each. It would not be a good use of my time staring at calls for half a work day doing nothing, so I’m looking for headphone that would help alleviate that.
- Lightweight, comfortable to wear
- Good battery life
- Okay sound quality, noise cancellation
- Also noise cancellation but for the mic
- Big plus: a way to mute/unmute call with gesture
For now almost nothing fit the bill. Jabra 4 Active has the last feature that I think would be useful, but they are no longer stocking and has been reported to die randomly.
Apple Liquid Glass is kinda shite, and it is shite that Apple is forcing it upon us π
The saying goes:
Big corp’s graphic designers have to redesign their branding every 3 years, otherwise they will go out of work.
And I’m not here to promote this stereotype (I lookup to some great graphic designer), but Apple’s newest design system is a proof for that saying.
Here are the qualms that Nielsen/Normal group has over this so-called graphical innovation in iOS 26:
- Everything is on top of everything. Thanks to overly abused transparency, you have images on top of images, text on top of images and text on top of text.
- A lot of design patterns that stuck with iOS for an odd decade would be changed or removed, such as:
- Pull down to search in message/mail -> the searchbar is now always at the screen bottom
- Back buttons used to have description of the previous page -> not any more
- On Safari, the back/forward buttons now show/hide based on whether there are page to move forward/backward to instead of being disabled.
- Layouts, element states, are always changing. It insists upon itself
Please, for the love of god, stop changing UI & UX patterns that people have became accustomed to. You don’t need to shake everything that is recognizable about your brand every five years. And if you do, please take measured, calculated steps to changing them, because it will hurt your users’ usability by a lot, and a less usable phone is a less-likely-to-be-bought phone. Because, looking at this picture, does this scream “I’m a competent UX designer that puts user experience at the forefront of my work” to you?
I’m staying on iOS 18 3 3 They are changing the version numbering scheme for iOS, so now it means iOS of the year [20]26 for as long as you can. For people unfortunate enough to be cursed with this graphical atrocity, here is a remedy: Reducing transparency
CPython 3.14 is out π
It’s a very interesting release because of several things:
- We have a different PyPi (you get it? 3.14 == pi?)
- Freethreading (Disabling the GIL) is officially supported
What does freethreading means in term of performance:
- Almost to None if you don’t have any threading/asyncio code
- Around 2x improvement in certain cases
Comparing to previous version of CPython, it is also quite a bit faster.
Vite+ is a unified toolchain for webdev π
I personally am weary of setting up JS project with a crapton of tooling, so I can get behind any attempt to keep it unified. Look at Go & Rust people, they are already losing enough time on arguing about memory management & shits, imagine how unproductive they would be if code formatting is also something they have to argue about.
What Vite+ is promising to bundle in their toolchain:
- Vite (duh)
- Vitest (also duh)
- monorepo tooling: I myself dislike monorepo, but maybe because I haven’t work in large enough project.
- This is their own implementation, independent of Nx/Turborepo.
- Oxlint & Oxfmt from The JavaScript Oxidation Compiler, written in Rust for blazing fast performance
Vite+ is source available, not FOSS. That may not rub with certain people, but I can see corporation people looking forward to this to standardize their development process