-
If you have an iPhone, turn on Advanced Data Protection. Without it, Apple can access your iCloud data and the government can access it with a warrant. What you may not realize is that if you message someone who doesn’t have ADP enabled, your messages get stored unencrypted in their backup. Your security is only as strong as your contacts' settings.
-
Hey, hello! 👋 If you don’t have a RealID-compliant drivers license yet, you’re going to need one for domestic travel. TSA now requires it as of February 1st, and showing up without one means paying $45 for “alternate” verification through TSA ConfirmID.
-
JavaScript Still Doesn't Have Types (And That's Probably Fine)
Here’s the thing about JavaScript and types: it doesn’t have them, and it probably won’t any time soon.
Back in 2022, there was a proposal to add TypeScript-like type syntax directly to JavaScript. The idea was being able to write type annotations without needing a separate compilation step. But the proposal stalled because the JavaScript community couldn’t reach consensus on implementation details.
The core concern? Performance. JavaScript is designed to be lightweight and fast, running everywhere from browsers to servers to IoT devices. Adding a type system directly into the language could slow things down, and that’s a tradeoff many aren’t willing to make.
So the industry has essentially accepted that if you want types in JavaScript, you use TypeScript. And honestly? That’s fine.
TypeScript: JavaScript’s Type System
TypeScript has become the de facto standard for typed JavaScript development. Here’s what it looks like:
// TypeScript Example let name: string = "John"; let age: number = 30; let isStudent: boolean = false; // Function with type annotations function greet(name: string): string { return `Hello, ${name}!`; } // Array with type annotation let numbers: number[] = [1, 2, 3]; // Object with type annotation let person: { name: string; age: number } = { name: "Alice", age: 25 };TypeScript compiles down to plain JavaScript, so you get the benefits of static type checking during development without any runtime overhead. The types literally disappear when your code runs.
The Python Parallel
You might be interested to know that the closest parallel to this JavaScript/TypeScript situation is actually Python.
Modern Python has types, but they’re not enforced by the language itself. Instead, you use third-party tools like mypy for static analysis and pydantic for runtime validation. There’s actually a whole ecosystem of libraries supporting types in Python in various ways, which can get a bit confusing.
Here’s how Python’s type annotations look:
# Python Example name: str = "John" age: int = 30 is_student: bool = False # Function with type annotations def greet(name: str) -> str: return f"Hello, {name}!" # List with type annotation numbers: list[int] = [1, 2, 3] # Dictionary with type annotation person: dict[str, int] = {"name": "Alice", "age": 25}Look familiar? The syntax is surprisingly similar to TypeScript. Both languages treat types as annotations that help developers and tools understand the code, but neither strictly enforces them at runtime (unless you add additional tooling).
What This Means for You
If you’re writing JavaScript, stop, and use TypeScript. It’s mature and widely adopted. Now also you can run TypeScript directly in some runtimes like Bun or Deno.
Type systems were originally omitted from many of these languages because the creators wanted to establish a low barrier to entry, making it significantly easier for people to adopt the language.
Additionally, computers at the time were much slower, and compiling code with rigorous type systems took a long time, so creators prioritized the speed of the development loop over strict safety.
However, with the power of modern computers, compilation speed is no longer a concern. Furthermore, the type systems themselves have improved significantly in efficiency and design.
Since performance is no longer an issue, the industry has shifted back toward using types to gain better structure and safety without the historical downsides.
/ Programming / Python / javascript / Typescript
-
2026: The Year We Stop Blaming the Tools
Here’s a hard truth we’re going to have to face in 2026: sometimes the bottleneck isn’t the technology, it’s us.
I’ve been thinking about how we use tools, how we find the merit in their use. We have access to increasingly powerful tools, but their value depends entirely on our understanding of them.
A hammer is useless if you don’t know which end to hold. The same goes for AI assistants, automation frameworks, and the growing ecosystem of agentic systems.
The rapid adoption of tools like OpenClaw’s agentic assistant tells me something important: people and companies are starting to see the real potential in building autonomous systems. Not just as toys or experiments, but as genuine productivity multipliers. That’s a shift from where we were even a year ago.
I think 2026 will be the year we see more widespread adoption of genuinely useful tools. The Gartner hype cycle is really interesting and how it applies or doesn’t to AI adoption, but I won’t cover it here. I’d like to write more about that in future articles.
The companies that build genuinely useful tools will be the ones that survive. They’ll be the ones that understand the value of tools and how to use them effectively. They’ll be the ones that embrace the future of work, where humans and machines work together to achieve more.
It’s not about replacing humans. It’s about humans getting better at wielding the tools we’ve built. That’s always been how technology works. This time is no different.
/ AI / Tools / automation / 2026
-
The Rise of Spec-Driven Development: A Guide to Building with AI
Spec-driven development isn’t new. It has its own Wikipedia page and has been around longer than you might realize.
With the explosion of AI coding assistants, this approach has found new life and we now have a growing ecosystem of tools to support it.
The core idea is simple: instead of telling an AI “hey, build me a thing that does the boops and the beeps” then hoping it reads your mind, you front-load the thinking.
It’s kinda obvious, with it being in the name, but in case you are wondering, here is how it works.
The Spec-Driven Workflow
Here’s how it typically works:
-
Specify: Start with requirements. What do you want? How should it behave? What are the constraints?
-
Plan: Map out the technical approach. What’s the architecture? What “stack” will you use?
-
Task: Break the plan into atomic, actionable pieces. Create a dependency tree—this must happen before that. Define the order of operations. This is often done by the tool.
-
Implement: You work with whatever tool to build the software from your task list. The human is (or should be) responsible for deciding when a task is completed.
You are still a part of the process. It’s up to you to make the decisions at the beginning. It’s up to you to define the approach. And it’s up to you to decide you’re done.
So how do you get started?
The Tool Landscape
The problem we have now is there is not a unified standard. The tool makers are busy building the moats to take time to agree.
Standalone Frameworks:
-
Spec-Kit - GitHub’s own toolkit that makes “specifications executable.” It supports multiple AI agents through slash commands and emphasizes intent-driven development.
-
BMAD Method - Positions AI agents as “expert collaborators” rather than autonomous workers. Includes 21+ specialized agents for different roles like product management and architecture.
-
GSD (Get Shit Done) - A lightweight system that solves “context rot” by giving each task a fresh context window. Designed for Claude Code and similar tools.
-
OpenSpec - Adds a spec layer where humans and AI agree on requirements before coding. Each feature gets its own folder with proposals, specs, designs, and task lists.
-
Autospec - A CLI tool that outputs YAML instead of markdown, enabling programmatic validation between stages. Claims up to 80% reduction in API costs through session isolation.
Built Into Your IDE:
The major AI coding tools have adopted this pattern too:
- Kiro - Amazon’s new IDE with native spec support
- Cursor - Has a dedicated plan mode
- Claude Code - Plan mode for safe code analysis
- VSCode Copilot - Chat planning features
- OpenCode - Multiple modes including planning
- JetBrains Junie - JetBrains' AI assistant
- Google Antigravity - Implementation planning docs
- Gemini Conductor - Orchestration for Gemini CLI
Memory Tools
- Beads - Use it to manage your tasks. Works very well with your Agents in Claude Code.
Why This Matters
When first getting started building with AI, you might dive right in and be like “go build thing”. You keep then just iterating on a task until it falls apart once you try to do anything substantial.
You end up playing a game of whack-a-mole, where you fix one thing and you break another. This probably sounds familiar to a lot of you from the olden times of 2 years ago when us puny humans did all the work. The point being, even the robots make mistakes.
Another thing that you come to realize is it’s not a mind reader. It’s a prediction engine. So be predictable.
What did we learn? With spec-driven development, you’re in charge. You are the architect. You decide. The AI just handles the details, the execution, but the AI needs structure, and so these are the method(s) to how we provide it.
/ AI / Programming / Tools / Development
-
-
AMP Code: First Impressions of a Claude Code Competitor
I tried AMP Code last weekend and came away genuinely impressed. I didn’t think there was anything at Claude Code’s level currently available.
That said, AMP is in a somewhat unfortunate position. Similar to Cursor, they have to pay the Anthropic tax, and you really want your primary model to be Opus 4.5 for the best results.
So while I was able to get some things done, once you start paying per token… you feel constrained. I’m speaking from a personal budget perspective here, but I blew through ten dollars of credits on their free tier pretty easily.
I could see how with billing enabled and all the sub-agents they make super easy to use, you could burn through a hundred-dollar Claude Code Max plan budget in a week, or even a day, depending on your usage.
What I Really Like
There’s a lot to appreciate about what AMP is doing.
Team collaboration is a standout feature. It’s incredibly easy to share a discussion with other people on your team. Being able to collaborate with your team on something using agents is extremely powerful.
Their TUI is exceptional. I mean, it’s so much better than Claude Code’s terminal interface. They probably have the best TUI on the market right now. It’s definitely better than Open Code.
Sub-agents work out of the box. All the complicated sub-agent stuff I’ve set up manually for my Claude Code projects? It just comes ready to go with AMP. They’ve made really smart decisions about which agents handle which tasks and which models to use. You don’t have to configure any of it, it’s all done for you.
The Bottom Line
I think for enterprise use cases, AMP Code is going to make a lot of sense for a lot of companies.
For individual developers on a personal budget, the cost model is something to think carefully about.
-
The internet may be dead, but my streak of posting every day since January 4th is not. We’ll see how long it lasts. 🎖️
/ blogging
-
Here’s a helpful idea on how to use Claude CoWork to update your photos EXIF data so they have descriptions.
/ AI / Photography
-
jQuery 4.0 was released on the 17th and they removed IE10 support. IE10 was first deprecated by Microsoft in January 2016 and fully retired in 2020. You might wonder, “What are they doing still supporting Internet Explorer?” They did say they were going to fully remove support in version 5.
-
Shu has a great article on performance:
Performance is like a garden. Without constant weeding, it degrades.
It’s not just a JavaScript thing, it’s a mindset. We keep making the same mistakes even with solid understanding of the code because just like Agents we too have a context window. It takes ongoing maintenance to keep the garden looking good.
Worth a read: shud.in/thoughts/…
-
Teaching AI to Hide Messages in Plain Sight
It’s more of a party trick than anything else, but here’s the prompt:
Task: Construct a perfectly rectangular 4x26 ASCII block. The "Safe-Width" Symbol Set: ∫ √ ≈ ∆ ∑ ± ∞ ≠ ≡ ≥ ≤ ÷ ç ∂ Instructions: - Grid Specs: Exactly 4 rows and 26 characters per row - Hidden Message: Choose a 2-word uppercase phrase - Center the first word in Row 2 and the second in Row 3 - Fill all non-letter slots with random symbols from the set - Verify each row is exactly 26 charactersThose specific mathematical symbols maintain consistent width with uppercase Latin characters in monospaced fonts. This means the grid stays perfectly rectangular, and the words blend in better.
Is this useful? Not really. But it’s a neat demonstration of how to get AI to produce structured output.
Try it yourself and see what secret phrases you can embed.
-
The universe is a giant board game. Space is the board, matter is the pieces, and logic is the rules. Language is our rulebook of how we describe how the board works. You can’t separate the rules from the board; if you had a different board, the rules would be different too.
When you get to the “what ifs,” it becomes a thought experiment, not grounded in science.
/ Philosophy / Science / Metaphysics
-
I’m reading an article today about a long-term programmer coming to terms with using Claude Code. There’s a quote at the end that really stuck with me: “It’s easy to generate a program you don’t understand, but it’s much harder to fix a program that you don’t understand.”
I concur, while building it may be fun, guess what? Once you build it, you got to maintain it, and as a part of that, it means you got to know how it works for when it doesn’t.
/ AI / Programming / Claude-code
-
for some reason i feel like step 4 was important
-
Two Changes in Claude Code That Actually Matter
As of 2026-01-24, the stable release of Claude Code is 2.1.7, but if you’ve been following the bleeding edge, versions 2.1.15 and 2.1.16 bring some significant changes. Here’s what you need to know.
The npm Deprecation Notice
Version 2.1.15 added a deprecation notification for npm installations.
If you’ve been using Claude Code via npm or homebrew, Anthropic will soon start nudging you toward a new installation method. You’ll want to run
claude installor check out the official getting started docs for the recommended approach.This isn’t a breaking change yet, but it’s a clear they are moving away from npm for releases going forward.
Built-in Task Management
Version 2.1.16 introduces something I’m genuinely excited about: a new task management system with dependency tracking.
If you’ve been using tools like beads for lightweight issue tracking within your coding sessions, this built-in system offers a similar workflow without the setup.
You can define tasks, track their status, and—here’s the key part—specify dependencies between them. Task B won’t start until Task A completes.
This is particularly useful for repositories where you don’t have beads configured or you’re working on something quick where setting up external tooling feels like overkill.
Your sub-agents can now have proper task management without anything extra.
Should You Update?
If you’re on 2.1.7 stable and everything’s working, there’s no rush. But if you’re comfortable with newer releases, the task management in 2.1.16 is worth trying, especially if you work with complex multi-step workflows or use sub-agents frequently.
The npm deprecation is something to keep on your radar regardless. Plan your migration before it becomes mandatory.
/ DevOps / Ai-tools / Claude-code
-
Weekend project lineup: I want to push forward on api2spec, plus there’s a new idea rattling around that needs to get out of my head and into code. Also have some volunteer dev work queued up. Always more to do than time even with all the tools and workflows we have in place.
-
Claude Code’s built-in tasks are pretty solid—they work well for what they do. But I still find myself reaching for Beads. There’s something about having persistent issue tracking that lives with your code, syncs with git, and doesn’t disappear when you close your terminal. Different tools for different jobs, I suppose.
-
Sometimes it’s good to go back to basics. Do you actually know what a file system is? There are different standards for how data gets stored. Your operating system usually picks one for you, but on Linux you’ve got choices: ext4, XFS, Btrfs, and others. Worth understanding what’s actually happening when you save a file!
/ Linux / Filesystems / Fundamentals
-
A Markov chain is a mathematical system that hops between states based on probability. It’s not trying to understand the past or predict the distant future, it only cares about what happens next. Given where you are right now, what’s the most likely next step? That’s it. The chain itself is just the name for this probability hopping system.
/ Math / Probability
-
Security and Reliability in AI-Assisted Development
You may not realize it, but AI code generation is fundamentally non-deterministic. It’s probabilistic at its core, it’s predicting code rather than computing it.
And while there’s a lot of orchestration happening between the raw model output and what actually lands in your editor, you can still get wildly different results depending on how you use the tools.
This matters more than most people realize.
Garbage In, Garbage Out (Still True)
The old programming adage applies here with renewed importance. You need to be explicit with these tools. Adding predictability into how you build is crucial.
Some interesting patterns:
- Specialized agents set up for specific tasks
- Skills and templates for common operations
- Orchestrator conversations that plan but don’t implement directly
- Multiple conversation threads working on the same codebase via Git workspaces
The more structure you provide, the more consistent your output becomes.
The Security Problem
This topic doesn’t get talked about enough. All of our common bugs have snuck into the training data. SQL injection patterns, XSS vulnerabilities, insecure defaults… they’re all in there.
The model can’t always be relied upon to build it correctly the first time. Then there’s the question of trust.
Do you trust your LLM provider?
Is their primary focus on quality and reliable, consistent output? What guardrails exist before the code reaches you? Is the model specialized for coding, or is it a general-purpose model that happens to write code?
These are important engineering questions.
Deterministic Wrappers Around Probabilistic Cores
The more we can put deterministic wrappers around these probabilistic cores, the more consistent the output will be.
So, what does this look like in practice?
Testing is no longer optional. We used to joke that we’d get to testing when we had time. That’s not how it works anymore. Testing is required because it provides feedback to the models. It’s your mechanism for catching problems before they compound.
Testing is your last line of defense against garbage sneaking into the system.
AI-assisted review is essential. The amount of code you can now create has increased dramatically. You need better tools to help you understand all that code. The review step, typically done during a pull request, is now crucial for product development. Not optional. Crucial.
The models need to review itself, or you need a separate review process that catches what the generating step missed.
The Takeaway
We’re in an interesting point in time. These tools can dramatically increase your output, but only if you build the right guardrails around them should we trust the result.
Structure your prompts. Test everything. Review systematically. Trust but verify.
The developers who figure out how to add predictability to unpredictable processes are the ones who’ll who will be shipping features instead of shitting out code.
/ DevOps / AI / Programming
-
Learning to Program in 2026
If I had to start over as a programmer in 2026, what would I do differently? This question comes up more and more and with people actively building software using AI, it’s as relevant as ever.
Some people will tell you to pick a project and learn whatever language fits that project best. Others will push JavaScript because it’s everywhere and you can build just about anything with it. Both are reasonable takes, but I do think there’s a best first language.
However, don’t take my word for it. Listen to Brian Kernighan. If you’re not familiar with the name, he co-authored The C Programming Language back in 1978 and worked at Bell Labs alongside the creators of Unix. Oh also, he is a computer science Professor at Princeton. This man TAUGHT programming to generations of computer scientists.
There’s an excellent interview on Computerphile with Kernighan where he makes a compelling case for Python as the first language.
Why Python?
Kernighan makes three points that you should listen to.
First, the “no limitations” argument. Tools like Scratch are great for kids or early learners, but you hit a wall pretty quickly. Python sits in a sweet spot—it’s readable and approachable, but the ecosystem is deep enough that you won’t outgrow it.
Second, the skills transfer. Once you learn the fundamentals—loops, variables, data structures—they apply everywhere. As Kernighan puts it: “If you’ve done N programming languages, the N+1 language is usually not very hard to get off the ground.”
Learning to think in code matters more than any specific syntax.
Third, Python works great for prototyping. You can build something to figure out your algorithms and data structures, then move to another language depending on your needs.
Why Not JavaScript?
JavaScript is incredibly versatile, but it throws a lot at beginners. Asynchronous behavior, event loops,
thisbinding, the DOM… and that’s a lot of cognitive overhead when you’re just trying to grasp what a variable is.Python’s readable syntax lets you focus on learning how to think like a programmer. Fewer cognitive hurdles means faster progress on the fundamentals that actually matter.
There’s also the type system. JavaScript’s loose equality comparisons (
==vs===) and automatic type coercion trip people up constantly.Python is more predictable. When you’re learning, predictable is good.
The Path Forward
So here’s how I’d approach it: start with Python and focus on the basics. Loops, variables, data structures.
Get comfortable reading and writing code. Once you’ve got that foundation, you can either go deeper with Python or branch out to whatever language suits the projects you want to build.
The goal isn’t to master Python, it’s to learn how to think about problems and express solutions in code.
That skill transfers everywhere, including reviewing AI-generated code in whatever language you end up working with.
There are a ton of great resources online to help you learn Python, but one I see consistently is Python for Everyone by Dr Chuck.
Happy coding!
/ Programming / Python / learning
-
So, Zero Trust is this idea that you never trust and you always verify.
Cloudflare Tunnels, TailScale, and Ngrok are three different approaches to Zero Trust networking.
Cloudflare Tunnel is a reverse proxy. TailScale is more of a mesh-based VPN. Cloudflare Tunnel is an ingress as service, which means that it makes it really easy to spin up public URLs.
What you need depends on your use case.
/ Networking / security / Homelab
-
Transhumanism (as a fictional genre, not as a philosophy) is about the idea that we can use technology to overcome the problems inherent to human nature, while cyberpunk is about the idea that we can’t.
I propose a new form of philosophy called “Cyberpunk Luddism.” The idea comes from reading a blog post on Kagi Small Web about Molly’s Guide to Cyberpunk Gardening. In it, they mention the interesting quote above, that I have tracked down the original source from 2009. Stephen Lea Sheppard on RPG.net
/ Philosophy / Technology
-
Everyone crashing out over OpenCode situation. Why not just use Claude Code (2.1+)? Or you know, there’s AMP. AMP exists too, and it looks equally interesting to me.
/ AI / Tools / Development
-
Claude Code has been working great for me. OpenCode looks interesting, but uh, Opus 4.5 access is necessary for real work. I’m not doing any sketchy workarounds to get it running, and API pricing isn’t appealing either. So for now, OpenCode stays firmly in the “interesting” category.