My old R&D team built the platform meant to carry a hundred-odd engineers off a PHP monolith, and it got scrapped. I'd like to blame the report, but turning their work into a number the business cared about was my job, and I didn't do it. #EngineeringLeadership #PlatformEngineering
Matt Cockayne
Matt Cockayne
@phpboyscout.uk
Always leave the codebase better than you found it. Go and Rust tooling, and making releases something you can prove came from you. phpboyscout.uk
16 followers70 following38 posts
Agents wrote 42 //nolint comments into my encryption code in a matter of days. "Bounded by the caller" was load-bearing and no one had proved it, and one more nearly threw away the integrity check on encrypted vulnerability reports. So I went through them one at a time. #golang #AIAgents
I once had four pitch decks for the same piece of work, and none of them led with the engineering argument, because that was the one that never worked. Tech debt belongs to the company, but the moment you promise to pay it down, it's your name on it. #TechDebt #Leadership
Two encrypted emails in twenty years, and the usual way a published PGP key fails is that its private half rots. A walkthrough where there's no private key anywhere to lose: gpg encrypts to a cert whose secrets live in KMS, and you read it back. #OpenPGP #AWS
I finally asked my Go framework the rude question: how big is a tool that does nothing? 81 MB, and 58% of it was SDKs it would never call, sat behind a comment of mine promising an opt-out that Go can't provide. Now 34 MB, plus the bill for it. #golang
AI found a 22-year-old way to own most of the PHP web. The fix shipped in a day. The bill went to a handful of maintainers and every volunteer with a club website to check. On PHP2Shell, and the drawer of bugs we all mark 'not exploitable'. #InfoSec #OpenSource
Pretty much every company I've worked for has told me it has a blameless culture. I can't think of an incident I've been near with no blame in it. Blameless was meant to make it safe to tell the truth about what you did, which is a long way from nobody having done anything. #SRE #Leadership
Ask five people to pick holes in something and they'll probably end up agreeing... and not because they're right. Models are trained on us, so I suspect they do it too. I set two rival models on one review with a single rule, do not manufacture agreement, and what survived went into the spec. #AI
I deleted 400 lines of my own OpenPGP code, swapped in go-crypto, and the tests passed... not what I'd hoped for. My reason turned out to be nonsense. But ECDH decryption with a KMS key, and a stdlib-only build, refused to die, so there was a better one waiting for me. #golang
For a month Bytespider was the busiest AI crawler on my blog, growing fast. Then I checked Cloudflare's verified-bot field: 515 real requests, 13,573 fakes. Over half of all "AI crawler" traffic failed verification and was hunting for .env.bak and id_rsa. A user agent is just a claim.
Two libraries both caught SIGINT. Both were right. signal.Notify is additive, so nothing errored: two shutdown drivers raced and context.Cause became a coin flip. Why go/controls no longer grabs signals by default. #golang
Fourteen agent sessions, fourteen projects, one head. Agents made the doing cheap. What costs me now is the arriving: walking into each pane cold and digging what it needs from me out of a wall of text. So I taught them to put the verdict first and the ask last. #AIAgents #DevEx
Signing releases sits on the to-do list for years looking bigger than it is. Ten minutes, a throwaway key, and gpg saying Good signature (then BAD when you tamper with the file) tells you what a signature actually is. Every command validated against v0.5.3. #golang
I had three AI providers vote on what happened at my Sunday night D&D game. The voting mechanism took forty lines. Working out what a 'fact' even is took the weekend. #DnD #AI
Locked my release bucket write-once in the morning, took it off by teatime. A half-published tag or a leaked secret could never be corrected. It stopped what I could already detect and guaranteed what I couldn't. #DevOps
A $270 CI bill landed, so I read the receipt line by line. The scary jobs (mutation, fuzz, cross-arch) were 5.7% of merge-request minutes. Renovate's branches were nearly half. Fixing the rest comes to something like 40% fewer minutes, and I haven't dropped a single test. #CICD #Testing
My homelab ran out of memory, not disk. Two weeks of clever tuning bought time but added zero capacity. So: a GitLab runner fleet that scales to zero. idle_count is fixed at 0. Workers get 200 GB (not a typo). #GitLab #HomeLab
I took someone off a job because they were burning out. Two days without a break, not listening, getting my hand-written code confidently backwards. They were also a chat session. So I asked for handover notes and brought in a fresh pair of eyes. #AI #DevLife
My photo-culling tool spent 38 minutes building v0.2.0, then the kernel OOM-killed the compiler on an OpenAI SDK the app has never once called. The fix was one dull line. What the OOM had been hiding was the interesting bit. #golang
One line in tls. Twelve releases, four waves, every one gated on me. An architectural review called it the estate's principal systemic risk. The bill for doing the split properly, and how I'm getting it down. #Golang #Monorepo
A CI job printed 'failed … 404 Not Found' and then 'Job succeeded'. 'Never fail the pipeline' had become 'always exit zero', which is a much stronger claim. Yellow was the answer all along. Report and carry on. Just don't report and succeed. #CICD
To append four lines to one YAML file, the release job cloned a decade of posts. The sparse recipe in the ticket looked right and silently emptied the worktree; the append would have replaced the file. A throwaway fixture caught it in three minutes. #golang
I wrote an extraction playbook after doing one easy module. Then chat, the hardest package in the codebase, went through it and broke step six. A process doc is a hypothesis until the hard case runs through it. #golang
A manager went back to engineering at exactly the same level. Same number on both sides of the ladder. Everyone around him called it a demotion anyway. Management is a choice. It was never a promotion. #EngineeringManagement #CareerLadder
21 agent-written fixes, all green, and I couldn't tell which ones fixed anything. So I asked: did you reproduce the bug first? Failing test on untouched main, then green, siblings sane throughout. Cheap, glanceable, hard to fake. #AIAgents #Testing
Decomposition stories only tell you what came out. The hard calls were the four packages that said no: one got deleted, two stayed for opposite reasons, one got widened. 'Extract or don't' isn't a big enough vocabulary. It needed five words. #golang
Went to check a kaniko flag and found the project had been archived a year earlier. All eight image repos pinned to a release nothing would ever patch. The replacement was the easy part. The real find: the builder was never why the images weren't reproducible. It was litter. #DevOps #Containers
I scored all 27 GTB packages, four ways each. 108 numbers. The lesson: value and ease of extraction aren't correlated. chat was the most valuable AND the hardest to shift. And the column I trusted most was the one that lied. #golang
My support bot logs every question it can't answer as a 'documentation gap'. Took me two weeks, three models and a hostile rubric to learn 'can't answer' is four different failures. One of them was me. #RAG #Documentation
I wanted keryx to make reels without ever seeing a disk, so FFmpeg went into a Wasm sandbox. Then I wanted the hardware back. The escape hatch I planned turned out to be french doors: a native engine, same afero filesystem, no shell. And I made myself write down the cost. #golang
Everyone scrapes FFmpeg stderr for a progress bar. afmpeg does not run the CLI, so there is no line. I watched bytes, then gave the engine a side channel... and the fraction still read 1.000 for a whole render. The fix: decide who wins, and let -1 mean "can't tell". #golang
Issues are the most tempting corpus in any repository: real questions, maintainer answers, already indexed. phpbotscout doesn't read them, and the reason isn't attackers. It's a maintainer who was right in 2024 and never went back to edit. Issues can point; they can't tell the bot what to say. #RAG
One Rust repo, 170GB of build artefacts, and all three slots on my runner for an hour while everything else queued behind it. I split it into twelve repos and kept one workspace. The bill: propagation. Still the right call. #rustlang
I went looking for a shell script and found eleven variants of it, on hundreds of laptops I couldn't reach, launching stale images into FedRAMP clusters. Bash didn't fail. The script just needed changing everywhere at once, and that's the day it stops being a script. #golang #devops
Every chat with gtb used to open by loading all 54 of its command schemas, 112 KB of JSON, before anyone typed a word. I called it a feature. go/mcp trades the floodlight for a lantern: three tools, 691 bytes, at any catalogue size. #MCP #MCP
You are up to date.