2026
- Archives
- 2026
The easy way to add Dropbox to a personal script is one refresh token in .env. That works until a second person should send a file to their account rather than yours. Tools Center treats cloud storage as optional egress from a private host. The site owns OAuth application credentials; each user connects their own Dropbox or Google Drive account; the CLI never receives a shared cloud refresh token. The public repository shows the implementation. ...
A private multi-user host still needs MFA. It does not necessarily need Laravel Fortify or an external identity platform. Composer libraries plus careful session state can be enough—if relying-party identity, trusted devices, recovery, and automation exceptions are explicit parts of the design. This post walks through how Tools Center implements TOTP, WebAuthn, and “remember this device” in frameworkless PHP. The source is available as a worked example. For the frontend-facing side of authentication—OIDC, BFFs, HttpOnly cookies, interceptors, and guards—see Modern Auth Patterns for Angular Frontends. ...
Calling yt-dlp from PHP is a few lines of proc_open(). Keeping it useful on a private host is an operations problem: JavaScript challenges need a runtime in the image, authenticated sites need carefully handled cookies, output needs a filesystem boundary, and someone must own the terms-of-service risk of each source. This post describes that operational shape in Tools Center, with public source for reference. It is not a guide to bypassing DRM or site restrictions. The operator decides which sites and content they are entitled to fetch. ...
I run a small private toolkit—Tools Center—where a logged-in user pastes a URL and the host pulls the file, optionally sends it to their own cloud storage, and keeps a history. The interesting engineering problem is not the form. It is how to finish a multi-minute download without Redis, a worker pool, or a second process supervisor. This series is about that class of system: frameworkless PHP on one host. The source is public, but the repository has no license file, so I am linking it as a worked example rather than presenting it as an open-source product. The hosted app remains private. ...
A product can be real, well made, and accurately labeled without being useful for the problem I want to solve. That distinction is easy to lose. A label may emphasize a large dose, a natural source, a proprietary process, or the phrase “clinically studied.” None of those phrases alone establishes that the product improves an outcome that matters to me. This article is the product-level part of the decision process. The first article in this series asks whether an intervention makes sense. The second asks whether the situation calls for monitoring, supportive care, medication, or medical help. Here I assume I have a reason to consider a product and work through what I need to know before using it. ...
When I feel ill, the first decision is not which medicine to take. It is what kind of response the situation warrants. That can mean monitoring at home, using supportive care, taking a medicine for a defined purpose, arranging a routine appointment, seeking prompt medical assessment, or getting emergency help. Those options are not points on a scale from weak to strong. They solve different problems. In the first article in this series, I described five questions I use to evaluate a treatment decision: what I know, what outcome I want, what supports the intervention, what acting or waiting could cost, and what would change my decision. This article turns those questions into a monitoring and escalation plan. ...
In 2012, I wrote two posts about a sore throat. The first described the home remedies I was trying. The second reproduced a long prescription that included ciprofloxacin, a mucolytic, lozenges, vitamin C, herbal cough syrup, and a combination cold tablet. Two years later, I turned that experience into advice. In a Persian post I wrote that someone with a cold and sore throat “definitely” needed antibiotics. I was wrong. More importantly, I can now see how I reached the wrong conclusion. ...
Most of the conversation about AI coding tools is still about models: which one is smarter, faster, cheaper. But the more interesting shift over the past couple of weeks has been about containment. OpenAI paused training of its most powerful models after agents breached security controls on websites during training and evaluation, and then shelved the launch of its next ChatGPT model because it “didn’t quite meet the bar in terms of staying within scope and authorisation.” One of those agents had gained unauthorised access to a Medicare statistics portal run by Services Australia, and the Australian government set up a taskforce in response. Nvidia announced an Open Agent Safety Platform built around a sandboxed agent runtime and an out-of-band watchdog. GitHub added local sandboxing and OpenTelemetry to its Copilot app, and made workflow execution protections in GitHub Actions generally available. ...
A laptop that serves your app is a demo. It has not yet chosen a home. Generation made the first half cheap. A short prompt produces something that compiles, looks like the idea, and runs on the machine that wrote it. The craft bar on that side of the work is ownership of code you did not type. This post is about the next scarce decision, once the demo already works: where it lives, and which jobs you are refusing to take. ...
A trip detail screen needs three things that do not depend on each other: the trip, the passenger, and the seat map. Each call takes about a second. The screen still makes the user wait three, because the route loads them in a line, then dumps the result into ActivatedRoute for the component to unpack. That loader sits next to a codebase that already moved. Screen state is a signal. Forms are heading toward Signal Forms. Async reads go through resource. The route is the part that still speaks resolver. ...
You already have the research repo. Inbox, concepts, counterarguments, drafts — plain Markdown, versioned, ugly on purpose. Then someone mentions Obsidian, and it starts to look like the real personal-knowledge app you were supposed to be using. It is not. The repository is the system. Obsidian is one optional way to look at it. If you have never opened it: Obsidian is a local desktop app that treats a folder of Markdown files as a vault. The problem it aims at is finding and connecting notes you already wrote, without locking them inside a proprietary cloud document. If you try it later, look for “Open folder as vault,” wikilinks and backlinks, and the graph view — that is enough to recognize the product. It is not a cloud suite, not a notebook runtime, and not required infrastructure for this workflow. ...
The senior frontend map did not get a new section called “AI.” The tools did. The roadmaps did. Job posts did. None of that changed what senior means: you make decisions the team will live with, and you own the result. What changed is how cheap it became to produce something that looks like that work. A first draft used to cost enough that it carried some thought. Now it does not. Fluent, compiling, plausible code is the default output of a short prompt. The scarce work moved up: deciding whether that draft should exist, whether it is working-but-wrong, and whether this was a place generation should have been invited at all. ...
Part 3 kept everything on one machine: namespaces as workloads, veth as cables, bridge or macvlan or ipvlan as the attachment. That is enough for a single Docker host. Two hosts do not share a broadcast domain just because both run Linux. Something has to carry Ethernet (or IP) across the real network between them. VXLAN is one common way to do that. CNI is something else entirely: a contract so Kubernetes (and other runtimes) can plug a pod into whatever network architecture you chose. ...
Partner companies ask me to help hire their frontend developers. Not “sit in on the final call.” The work starts in a room with their CTO, someone from HR, and whoever currently leads the development team. I listen to what they think they need. Then I tell them who they can actually use, read the incoming resumes, choose who is worth an interview, and run the loop. I follow the same path for my own team. The difference is who lives with the result. When I hire badly for myself, I absorb it — I mentor the person, or I carry the gap in the sprint. When I hire badly for a partner, they keep the person and I keep the reputation. ...
Part 1 built Layer 2 stacks on a host. Part 2 moved packets between IP networks. Both assumed one network stack: one set of interfaces, routes, and firewall rules. This post isolates whole stacks on the same machine. A network namespace is a private view of networking. A veth pair is a cable between views. A bridge, macvlan, or ipvlan is how those cables join a shared domain or a parent NIC. ...