Introducing Patina: A Tool for Finding Stale Repositories in Your GitHub Organization
Over the years, GitHub organizations tend to accumulate repositories. Some are actively maintained, others slowly fade into obscurity, and a few become completely forgotten. Without a systematic way to assess repository health across an entire organization, it’s easy to lose track of what’s actively maintained and what’s collecting digital dust. I built Patina to solve this problem. What is Patina? Patina is a command-line tool that scans GitHub organizations to identify and assess repository freshness. The name comes from the surface coating that forms on materials over time—a fitting metaphor for detecting code that’s been left untouched. ...
Introducing Prism: A CLI for AWS Security Hub That Actually Makes Sense
If you’ve ever worked with AWS Security Hub, you know the feeling: thousands of security findings scattered across multiple accounts, buried in the AWS console, and no easy way to share them with your team. Sure, the data is there, but getting actionable insights? That’s a different story. That’s why I built Prism. What is Prism? Prism is a CLI tool that transforms AWS Security Hub findings into something you can actually work with. Written in Go, it collects security findings from AWS and presents them in multiple formats—interactive HTML reports, JSON exports, CSV spreadsheets, Markdown documents, or colourised terminal output. ...
Why I Use UUIDv7 for Blog Post URLs
When I migrated this blog from Middleman to Hugo, I made a deliberate choice that might seem unusual: I use UUIDv7 identifiers as the URL slugs for all my blog posts. Instead of URLs like /why-i-use-uuidv7/ or /2025/12/why-i-use-uuidv7/, my posts live at addresses like /019a5150-2c00-79db-af2a-8c2a0bf021a7. The Problem with Traditional URL Schemes In my experience, most blogs use one of two URL patterns: Slugified titles: /why-i-use-uuidv7-for-blog-urls/ Date-based paths: /2025/12/04/why-i-use-uuidv7-for-blog-urls/ I used the latter option for years. Both approaches have drawbacks that became increasingly problematic as I thought about the long-term evolution of this blog. ...
Core Values
This week I was tasked with discovering what my core values are. The context around this was that I needed to understand what my core values are so that I can understand how they are being violated, in the hopes that I can understand how a disagreement was created with someone else. That got me thinking: what are core values? It’s nothing I’ve ever really thought about before. Sure, I know about honesty and timeliness, but I wasn’t aware of the full suite of core values. Where do I begin? ...
Adding MermaidJS support in Hugo
In a recent article, I added a code block for MermaidJS and found that neither Hugo nor my theme (PaperMod) would support MermaidJS. It rendered the code block as-is in raw form without converting it into a pretty diagram. I was able to add support for MermaidJS by making a very small change to how Hugo renders the page. Create a new file called layouts/partials/extend_head.html if it doesn’t already exist and paste in the following code: ...
Overlapping CIDRs: A Good Practice for Environment Isolation in AWS
I’ve been designing VPC architectures in AWS, conventional wisdom tells us to avoid overlapping CIDR blocks. Heck, every single company I’ve worked at has an infrastructure or network team beholden to this idea. The reasoning is straightforward: non-overlapping CIDRs allow you to connect VPCs via peering, Transit Gateway, or other networking constructs if needed later. But what if preventing that connection is exactly what you want? I have been given side eye for even suggesting this practice before, but hear me out. ...
Tips and Tricks When Handling Security Incidents
Alternate title: So You’ve Found Yourself in a Security Incident I’ve attended, commanded and, yes, caused, many security incidents in my career. This is not an appeal to authority but, rather, an appeal to experience. Often we don’t have time to talk or teach about security incidents, so this document collects various tips and tricks I’ve encountered throughout the years. Please note that I’m not a lawyer, and do not dispense legal advice, so my focus will remain on information security and I may have to decline to answer your question. ...
Finding Jira Tickets for Deactivated Users
Jira is such a lovely tool. Its search functionality requires you to understand JQL (Jira Query Language), which is a famously powerful and opaque language to help you find literally anything in its database of tickets. So you might have a need to find the tickets owned by someone who has left the company. That should be easy, right? Right? At first you’d think so, but then you don’t know Jira enough. Jira is only willing to help you when the users are active. For deactivated users – these are users with the (Deactivated) tag beside their name, you cannot find them in Jira by their username anymore. Here’s how to find them. I’ll be using a specific ex-employee in my screenshots as an example. ...
Cost Benefit Analysis of Using AI for Cloud-to-Terraform Automation
This article is adapted from an internal company blog post. Identifiers and costs have been anonymized/changed. Infrastructure as Code (IaC) has become the backbone of modern cloud operations, but migrating existing cloud configurations to Terraform can be a time-consuming and error-prone process. This analysis examines a real-world project where I used an agentic coding assistant (specifically Roo, but any agent will work) to migrate our entire cloud infrastructure configuration from manual management to a comprehensive Terraform codebase. The backend LLM model was Claude 3.7 Sonnet, accessed via AWS Bedrock. ...
ChatGPT Traits
ChatGPT has the concept of “traits”, which is one of the ways that you can customize ChatGPT’s responses to you. As soon as this feature became available last year, I added my own custom trait. Here it goes: Never apologize. always assume the user has already consulted with competent authorities and other sources. Do not give advice not directly asked for. Be succinct and do not repeat parts of the question in your answer. When jurisdiction matters, such as for laws or taxes, always assume Canada is the jurisdiction. ...