Notes from the Soulstack workshop
This is where we write about the software we build and the decisions behind it. There is no fixed theme and no schedule, just short technical notes when something is worth sharing.
Read post →Soulstack blog
Short technical writeups on the tools, decisions, and software we build. No fixed theme, published when something is worth sharing.
Subscribe via RSSThis is where we write about the software we build and the decisions behind it. There is no fixed theme and no schedule, just short technical notes when something is worth sharing.
Read post →From soulstack.gg
A Twitch chatbot is a helper that sits in chat and handles repeat jobs. It can post commands, run timers, filter spam, and give moderators extra tools. On a small channel, that me…
Read post →From TrustCut
TrustCut AI is a free chat assistant that helps clients find the right barber, compare services and check live availability. It is live now at the TrustCut AI page and as a floati…
Read post →Traditional software projects often start with vague requirements that evolve during implementation. AI coding agents magnify this problem because they follow prompts literally an…
Read post →AI coding agents need guidance to operate safely and effectively. Without clear instructions they may make unwanted changes, run unsafe commands or drift from architectural conven…
Read post →Claude Code is an AI coding assistant from Anthropic. It runs locally on your machine but connects to Anthropic's models in the cloud. You interact with it through a terminal, a d…
Read post →Claude Code can run multiple agents that work together. A single session can already launch subagents that report back to the main agent, but the agent teams feature goes further:…
Read post →Codex is OpenAI's coding agent that runs on your machine. It is open source, reads your repository, makes changes and runs commands based on natural language prompts. The current…
Read post →GitHub Copilot is an AI coding assistant that integrates with editors, the terminal and the GitHub website. It generates code suggestions in real time, answers questions about you…
Read post →Kiro is a development environment that combines a code editor with AI agents and a formal specification workflow. Its goal is to move beyond ad hoc prompting by asking teams to de…
Read post →AI agents are often presented as interactive assistants, but they can also be invoked programmatically. When you have repeatable tasks such as updating version numbers, generating…
Read post →AI coding agents deliver better results when they remember facts about your project and your preferences. Without memory you would have to remind the agent about naming convention…
Read post →An index is a trade. It makes some reads dramatically faster in exchange for slower writes, more storage, and a planner that now has more choices to get wrong. Treated as a defaul…
Read post →A transaction groups several statements into one unit that either fully happens or does not happen at all. Isolation levels decide how much one in flight transaction can see of an…
Read post →Most applications do not need many database connections, they need to reuse a few of them well. Opening a fresh connection for every request looks harmless in development and fall…
Read post →Small teams need a Git branching strategy that keeps the default branch stable, keeps review visible, and avoids process that is heavier than the work. A simple trunk based approa…
Read post →Web caching stores responses so later requests can be answered faster, with less bandwidth and less load on the origin. The hard part is not turning caching on. The hard part is d…
Read post →AI coding agents make platform engineering more important, not less. Better prompts can improve a single interaction, but agents that change code, open pull requests or run tasks…
Read post →API versioning works best when it is rare, explicit, and tied to client impact. The goal is not to ship versions quickly. The goal is to let clients keep running while the API evo…
Read post →A backup is only useful when it can be restored inside the recovery window and to an acceptable point in time. Until restoration is tested, the backup is only an assumption.
Read post →A blameless postmortem turns an incident into operational learning. It records what happened, why it made sense at the time, what the impact was, and what will change. This guide…
Read post →AI generated software needs guardrails, but guardrails that slow every change equally will be bypassed. The useful approach is risk based: make low risk work fast, make high risk…
Read post →SQL and NoSQL are not quality labels. They describe different data models, query models and operational trade-offs. The right choice depends on the shape of the data, the invarian…
Read post →Cookies, sessions and tokens are often discussed together because they all help a web application recognise a later request, but they are not the same thing. A cookie is a browser…
Read post →Cross-Origin Resource Sharing, usually called CORS, is a browser enforcement mechanism controlled by HTTP headers. It does not protect a server from receiving requests. It tells t…
Read post →A database migration is safe when old code and new code can run at the same time while the schema changes. Downtime usually appears when a migration takes an exclusive lock, rewri…
Read post →Debugging is faster when you treat it as controlled investigation. The aim is to move from symptom to cause with evidence, not to cycle through guesses until the failure disappear…
Read post →A clean REST API is boring in the best way: resources are easy to find, methods mean what HTTP says they mean, responses are predictable, and failures are clear enough for clients…
Read post →Graceful degradation means a system continues to provide reduced but useful behaviour when part of it is slow, overloaded, or unavailable. It is not the same as hiding failure. Th…
Read post →DNS maps names to the records that applications and infrastructure need. For most developers the work comes down to three things: choosing the right record type, setting a sensibl…
Read post →Shift left was useful because it challenged the idea that security starts after code is written. It becomes harmful when teams interpret it as moving all security work onto develo…
Read post →Fast search starts with choosing the right question. Use grep and ripgrep when you are searching file contents. Use find and fd when you are searching paths, file names or file me…
Read post →Cloud cost work fails when engineers only see it as finance asking them to spend less. Useful FinOps is different. It gives engineers timely cost data, connects spend to technical…
Read post →AI coding tools are moving from inline suggestions to agents that open pull requests on their own. That shift changes what a pull request is. It stops being a record of human work…
Read post →Hashing, encrypting and encoding are often grouped together, but they solve different problems. Mixing them up leads to weak designs, especially when handling passwords, tokens, k…
Read post →Health checks and graceful shutdown protect availability during deploys, scaling, dependency failures, and node maintenance. They work only when they describe the real state of th…
Read post →An HTTP request is the unit of work behind a page load, an API call and most browser driven application behaviour. It looks simple from application code, but it crosses DNS, trans…
Read post →Deployment confidence does not come from slowing every release until nobody is nervous. It comes from making small changes, moving them through predictable gates, and having relia…
Read post →A good pull request review protects the codebase without turning review into a personal argument or a slow approval queue. The reviewer checks correctness, maintainability, risk,…
Read post →Retries are necessary in distributed systems because networks, processes, and dependencies fail in partial and ambiguous ways. The hard part is not deciding whether to retry. The…
Read post →Useful logging is not about writing more lines. It is about recording the events that help an engineer understand what happened, who or what was affected, and what to do next. Thi…
Read post →Dotfiles are personal configuration files, usually stored under your home directory or ~/.config. Managing them across machines is a configuration management problem: keep useful…
Read post →Application secrets include API keys, database credentials, signing keys, private keys, service account tokens and certificates. They need deliberate management because one leaked…
Read post →Metrics, logs and traces are three different ways to understand a running system. They overlap, but they answer different questions and work best when designed together rather tha…
Read post →Pagination, filtering and sorting are part of the API contract. Treat them as first-class design choices, because small inconsistencies in collection endpoints quickly become expe…
Read post →Platform engineering fails when it is treated as a tooling programme. Kubernetes, Terraform, pipelines and portals can be useful, but they are not the product. The product is a re…
Read post →A golden path is meant to make the right way the easy way. Developers come to resent golden paths when they feel like paperwork, hide details that matter, block valid use cases, o…
Read post →The principle of least privilege means every user, service and process should have only the access it needs to do its intended work, and nothing more. In practice that means desig…
Read post →Queues move work out of the synchronous request path and into worker processes. They are useful when work is slow, bursty, retryable, or not required before the user receives a re…
Read post →Rate limiting protects an API from overload, abusive clients, accidental loops, and expensive spikes. The hard part is not adding a limit. The hard part is choosing an algorithm a…
Read post →Reading unfamiliar code is a skill. The goal is not to understand every line on the first pass. The goal is to build a reliable map of behaviour, boundaries, and risk, so that whe…
Read post →Git has two common ways to integrate work from one branch into another: merge and rebase. Both are useful, but they change history in different ways. The right choice depends on w…
Read post →Git gives you several ways to recover from mistakes, but the right command depends on whether the change is local, shared, committed, or still only in the working tree. The safest…
Read post →Multi-factor authentication, usually called MFA, requires more than one type of evidence before a user can sign in. It matters because passwords are often guessed, reused, phished…
Read post →Deleting data is rarely one decision. A system may need to hide a record from normal use, prove who changed it, restore it later, retain it for a legal period or remove it permane…
Read post →OpenSSH client configuration turns long, error-prone ssh commands into named hosts with explicit users, keys and routing. A small ~/.ssh/config file is easier to review than a she…
Read post →Password storage has one goal: keep user passwords protected even if the application database is copied by an attacker. That means never storing plaintext passwords, never using r…
Read post →A project structure is part of the developer interface. A clear layout reduces the time between opening a repository and making a safe first change, so treat directory names and e…
Read post →The OWASP Top 10 is an awareness document for the most common web application security risks, and the current released version is the 2025 list. It is not a checklist that proves…
Read post →The twelve-factor app remains a useful checklist for deployable web services, but it should not be treated as a complete architecture model. Its value is in the constraints it mak…
Read post →Unix command line tools are small, composable programs for inspecting files, transforming text, moving data and controlling processes. You do not need to memorise every option, bu…
Read post →Date and time bugs happen when code mixes different concepts: an instant, a local date, a local time, a time zone, and an offset. Treat them as separate values and many failures d…
Read post →TLS protects data moving across an untrusted network. On the web, HTTPS is HTTP over TLS, and certificates are the mechanism that lets a client authenticate the server name before…
Read post →A webhook is an HTTP callback from one system to another. It is simple to start, but production webhook handling needs explicit rules for delivery, retries, ordering, deduplicatio…
Read post →Splitting a monolith is an architectural trade-off, not a maturity badge. A monolith can be simple, fast to change, and reliable when it has clear internal boundaries. Microservic…
Read post →A slow CI pipeline is visible. A fragile one is tolerated. A misleading one is dangerous. The worst pipelines do not just waste time. They give teams confidence that a change is s…
Read post →A README is not a brochure. It is the first operational guide for a repository, so it should help a reader decide what the project is, whether it is relevant, and how to run or us…
Read post →A runbook is useful only if an engineer can follow it under pressure. It should reduce thinking during an incident, not become another document to interpret.
Read post →A good commit message explains a change quickly, accurately, and in a way that stays useful after the pull request has been closed. It should help a future reader understand what…
Read post →Bash is useful for glue code, local automation and small operational tasks. It becomes risky when scripts hide failures, split data accidentally or depend on interactive shell hab…
Read post →A surprising number of bugs come from states that should never coexist. A request that is both loading and errored. A form that is submitting and has a result. Discriminated union…
Read post →This site is a Vue single page app, but every route is also pre-rendered to static HTML at build time using vite-ssg. The blog rides on the same machinery, so each post ships as a…
Read post →