Sign in

Mathew Attlee

@codeinabox.hachyderm.io.ap.brid.gy
15 followers 5 following 130 posts

Code In A Box is a London based software development consultancy run by Mathew Attlee specialising in service and web development. 🌉 bridged from ⁂ hachyderm.io/@codeinabox, follow @ap.brid.gy to interact

PostsRepliesMedia
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 30/09/2026
I am surprised that many websites don't have a Content Security Policy, despite it being such a simple way to guard against cross-site scripting attacks. However to be fair, I didn't start using it until recently, even though it has being available across all browsers since 2016.
012
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 29/09/2026
Great post by @tempertemper on respecting users' browsing preferences www.tempertemper.net/blog/respectin…
tempertemper.net
Respecting your users’ preferences
Our users have already chosen how they want their devices to behave; here’s how we can respect those preferences on the web.
000
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 29/09/2026
Don't use containers as a security boundary for AI agents - they can break out of them depthfirst.com/research/containers-…
002
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 28/09/2026
I've been playing with nono, and it's very powerful for restricting what tools agents can call. nono.sh/docs/cli/features/tool-sand… #AICoding
nono.sh
Sandboxed Tool Execution - Nono Docs
Run selected commands in zero-trust command sandboxes with brokered chaining
000
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 24/09/2026
As someone with a tough inner critic, and a sufferer of imposter syndrome, I can definitely relate to this article, as I've had my moments in the senior engineer death spiral. sunilpai.dev/posts/the-senior-engin…
sunilpai.dev
the senior engineer death spiral
on proving yourself, burning out, and being a good teammate
000
Reposted by Mathew Attlee
Piccalilli @piccalilli.front-end.social.ap.brid.gy · 21/09/2026
There's been so much dry content about Temporal so far but Sophie Koonin has written about a nice creative usage here. localghost.dev/blog/time-based-back…
localghost.dev
Time-based background colour transitions with Temporal and CSS color-mix
I've given my website a bit of a refresh! There's a slightly updated layout if you're on desktop, plus I ditched the `etc` page and I've revamped my links page to be powered by raindrop.io. The minimalist theme is still minimalist, but a bit more fancy. The vaporwave theme has a newly jazzed-up nav bar with some adorable little icons. But the biggest change is to the city theme, which was previously a starry-sky dark mode theme. If you're reading this between the hours of 9pm - 5am, you might be wondering what all the fuss is about - it looks pretty much the same as it did before. That's because the theme changes depending on the time of day! You can select the time of day using the picker in the top right, after the theme switcher. I'm persisting the choice in session storage so you don't get attacked by sudden light mode when changing pages, but if you visit again in the future it'll reset back to "now". I was going to just turn the layout into a pastel lo-fi-aesthetic thing, but then I realised that a) I needed _some_ kind of dark mode and b) I'd miss the stars! So I thought... why not both? And why stop at just night and day? (Hat tip to Alistair Shepherd who did something similar with his beautiful Firewatch-inspired website.) Then I remembered that the Temporal API was available experimentally in Chrome and Firefox, and I'd been looking for an excuse to try it out. ## Introducing Temporal For the uninitiated, Temporal is a solution to the objectively terrible Date API in JavaScript. Date was based on Java's Date library, which was also objectively terrible and has long been deprecated. It's always really confusing that `Date` instances show either local or UTC time depending on which function you use to display them, and date operations are so fiddly that most of us turn to third party libraries like `date-fns` or `luxon`. Temporal massively simplifies the API, introducing some new concepts: * `PlainDateTime`: a date and time with no timezone (TZ) * `PlainDate`: a date with no time information and no TZ * `PlainTime`: a time with no date information and no TZ * `ZonedDateTime`: a date and time in a specified TZ `PlainTime` came in useful for this project, as we don't really care what the day is - only what time it is, so we know what colours to show. ### Getting the user's local time The first thing to do was figure out the time according to the user's browser. The `Temporal.Now` namespace has various methods for interacting with the current time, including `plainTimeISO()` which by default gives us a `PlainTime` in local time. (You can also pass in a time zone to get a zoned time.) const timeNow = Temporal.Now.plainTimeISO(); Now we need to know when to show the different colours. ## Defining the stages The day is split into four stages: sunrise, daytime, sunset and night. Daytime and night are long - 11.5 hours each - whereas sunrise and sunset each last 90 minutes. The background of the page has a two-colour gradient: --background: fixed linear-gradient(var(--bg-gradient-top), var(--bg-gradient-mid) 80%); The footer has an additional colour that's created with a linear gradient from transparent `oklch(0 0 0 / 0)` to the chosen third colour. background: linear-gradient(oklch(0 0 0 / 0) 40%, var(--bg-gradient-bottom)); This means the last colour sticks to the bottom of the page rather than stretching across the viewport height (it's hard to control even when you specify a percentage in the gradient). It also gives more of a glow that really looks like the sun rising/setting or the glow of the city, which I love. I defined an object for the stages and colours: const stages = { sunrise: { start: Temporal.PlainTime.from("06:30:00"), next: "day", color1: "oklch(0.618 0.3157 265.76)", color2: "oklch(0.8867 0.1222 328.24)", color3: "oklch(0.9529 0.1222 106.94)", }, day: { start: Temporal.PlainTime.from("08:00:00"), next: "sunset", color1: "oklch(58% 0.15433 300)", color2: "oklch(85% 0.22133 302)", color3: "oklch(98 0.22133 302)", }, sunset: { start: Temporal.PlainTime.from("19:30:00"), next: "night", color1: "oklch(0.6933 0.1899 297.53)", color2: "oklch(75.504% 0.24612 357.26)", color3: "oklch(88.591% 0.1422 62.595)", }, night: { start: Temporal.PlainTime.from("21:00:00"), next: "sunrise", color1: "oklch(25.27% 0.0919 276.73)", color2: "oklch(47.35% 0.284 283.78)", color3: "oklch(62.831% 0.23521 310.291)", }, }; CSS custom properties are easy to set via JS - you can use `root.style.setProperty`: root.style.setProperty( "--bg-gradient-top", "oklch(25.27% 0.0919 276.73)", ); Unlike `Date`, we don't have to do any gymnastics to compare Temporal instances: there's literally a `compare` function on each type of instance. Just like with other JS comparison functions, it returns `1` if the first instance is greater than the second, `0` if the two instances are the same, and `-1` if the first instance is less than the second. const compare = Temporal.PlainTime.compare // extracted for brevity switch (true) { case compare(timeNow, stages.sunrise.start) < 0 || compare(timeNow, stages.night.start) >= 0: { currentStageName = "night"; break; } case compare(timeNow, stages.sunrise.start) >= 0 && compare(timeNow, stages.day.start) < 0: { currentStageName = "sunrise"; break; } case compare(timeNow, stages.day.start) >= 0 && compare(timeNow, stages.sunset.start) < 0: { currentStageName = "day"; break; } case compare(timeNow, stages.sunset.start) >= 0 && compare(timeNow, stages.night.start) < 0: { currentStageName = "sunset"; break; } default: break; } Once we've got the stage name, we can look up the colours and set the custom property values. root.style.setProperty( "--bg-gradient-top", stages[currentStageName].color1, ); root.style.setProperty( "--bg-gradient-mid", stages[currentStageName].color2, ); root.style.setProperty( "--bg-gradient-bottom", stages[currentStageName].color3, ); I'm also setting a data attribute on the root so we can do some additional stage-based customisations, such as showing the stars when it's night. root.setAttribute("data-time", currentStageName); And that will give us our different gradient colours at different times of day! And _then_ I remembered that `color-mix` exists. Why restrict ourselves to just 4 times of day and 4 sets of colours, when we could make them... transition into each other????? ## Blending transitions with color-mix `color-mix` is an extremely cool CSS function that lets you, well, mix two colours together. You tell it what colour space you're working with, and the colours, and the browser magically outputs the mix between the two. background: color-mix(in oklch, color1, color2) Much like with gradients, you can also specify a percentage value for the colours, which indicates the proportions of the colours: background: color-mix(in oklch, color1 20%, color2) So I could gradually feed in a bit of the next stage's colour until the next stage took over completely. To get a percentage value for the next stage colour to feed in, I had to figure out how far through the current stage we are. First, I'm calculating the time until the next stage - super simple with the `until` function on `Temporal` instances: time1.until(time2) This gives us a `Temporal.Duration` which represents a period between two time points. So, for example, if it's 7:45pm now and we're calculating `timeUntilNextStage`: const timeUntilNextStage = timeNow.until(stages.night.start) console.log(timeUntilNextStage.toString()) // PT1H15M `Duration`s are stringified (and specified) using the ISO 8601 duration format, so "PT1H15M" means "period, time separator, 1 hour, 15 minutes".Time information appears after the `T`; if the duration had any date information in it, it'd appear before the `T`. We set `timeUntilNextStage` in the switch statement where we're deciding what stage we're in, for example: case compare(timeNow, stages.sunrise.start) >= 0 && compare(timeNow, stages.day.start) < 0: { currentStageName = "sunrise"; timeUntilNextStage = timeNow.until(stages.night.start); break; } Once we've got the duration representing time until the next stage, we need to know the duration between the start of the current stage and the start of the next stage - let's call it the "transition duration". For sunset-to-night and sunrise-to-day, the transition duration is always 90 minutes; for night-sunrise and day-sunset, it'd be 11.5 hours. I didn't want the colour mixing to happen all throughout the day, only around sunrise/sunset like in real life, so I just decided to hardcode the transition duration for day and night to be 90 minutes so it matches the other two. So for that, I can instantiate a `Duration` using the same ISO 8601 syntax: const entireTransitionDuration = Temporal.Duration.from("PT1H30M") Now I need to calculate the difference between the total duration and the time until next stage - basically, how far into the transition period we are, and therefore how much of a percentage we should mix in of the next colour. Handily, Temporal gives us a `subtract` function as well: const diff = entireTransitionDuration.subtract(timeUntilNextStage) Then to figure out the transition progress as a percentage, we can divide `diff` by `entireTransitionDuration`. We'll do that with the time values in seconds so we can divide them, using the instance's `total` function: const entireTransitionDurationInSeconds = entireTransitionDuration.total({ unit: "seconds" }) const diffInSeconds = diff.total({ unit: "seconds" }) const transitionProgressPercent = Math.round((diffInSeconds / entireTransitionDurationInSeconds)*100).toFixed() // gives us a string representation with 0 d.p. ### The midnight problem It's a little more complicated for the "night" stage, because that crosses midnight into the next day. Remember that our `PlainTime` only has time information, not date information - so if it's 10pm and you're asking it how long until sunrise at 6:30am, it'll give you a negative number! const now = Temporal.PlainTime.from("22:00") const sunrise = Temporal.PlainTime.from("06:30") const d = now.until(sunrise) // Temporal.Duration -PT15H30M This causes problems at the point where I calculate the diff, as it'll come out as a large number and completely throw off the calculations. I got around this by getting the absolute value of the duration with `.abs()`, so `timeUntilNextStage` will always be positive, even if it's before midnight: e.g. what was`-PT15H30M` will now be `PT15H30M`. Calculating the diff by subtracting that from a `transitionDuration` of 90 mins will always yield a negative number. case compare(timeNow, stages.sunrise.start) < 0 || compare(timeNow, stages.night.start) >= 0: { currentStageName = "night"; timeUntilNextStage = timeNow.until(stages.sunrise.start).abs(); break; } Then, we only calculate a transition percentage if `diff` is greater than 0: let transitionProgressPercent = 0; if (diffInSeconds > 0) { transitionProgressPercent = Math.round((diffInSeconds / entireTransitionDurationInSeconds) * 100); } This works for the daytime stage too: if it's more than 90 mins before sunset, it'll come out with a negative diff - so that will just display the daytime colours and no transition. ### Let's mix! Now we can use that percentage value (which will always be a whole number) in the `color-mix` function to dictate how much of the next colour we should interpolate. color-mix(in oklch, ${color1} ${transitionProgressPercent}%, ${color2}) I updated my `stages` object to include the next stage name as well: night: { start: Temporal.PlainTime.from("21:00:00"), next: "sunrise", color1: "oklch(25.27% 0.0919 276.73)", color2: "oklch(47.35% 0.284 283.78)", color3: "oklch(62.831% 0.23521 310.291)", }, // etc So we can get both colours dynamically when we set the variables with `color-mix`: root.style.setProperty( "--bg-gradient-top", `color-mix(in oklch, ${stages[nextStageName].color1} ${transitionProgressPercent}%, ${stages[currentStageName].color1})`, ); And that's how we transition the colours! ## Transitioning the transitions As a bonus touch, I wanted the colour change to transition smoothly when you switch between stages manually using the picker on the top right. By declaring my `bg-gradient-xx` variables using `@property`, I can tell the browsers that yes, they are definitely colours - and therefore they can be animated. Without this explicit custom property declaration, I could set the value of `--bg-gradient-top` to a number, or a position, or anything I wanted. By saying it's definitely a colour, the browser knows how to transition it into other values of the same type. I initially did this with `@property` declarations in the CSS: @property --bg-gradient-top { syntax: "<color>"; inherits: true; initial-value: oklch(...); } @property --bg-gradient-mid { syntax: "<color>"; inherits: true; initial-value: oklch(...); } @property --bg-gradient-bottom { syntax: "<color>"; inherits: true; initial-value: oklch(...); } Unfortunately, setting these in the CSS meant that you got a flash of whichever initial values I'd set before the JS kicked in and set the appropriate colours for time of day. If this page were server-driven, or always started from the same colour for everyone, it would've been fine. But the starting colour depends on your time zone and is only calculated when the initial JS runs. I got around this by setting the properties via JS instead: window.CSS.registerProperty({ name: "--bg-gradient-top", syntax: "<color>", inherits: true, initialValue: stages[currentStageName].color1, }); window.CSS.registerProperty({ name: "--bg-gradient-mid", syntax: "<color>", inherits: true, initialValue: stages[currentStageName].color2, }); window.CSS.registerProperty({ name: "--bg-gradient-bottom", syntax: "<color>", inherits: true, initialValue: stages[currentStageName].color3, }); I had to wrap these in a `try/catch` as it will throw if the property's already been defined. It wasn't super trivial to figure out if this property had already been set, as the CSS does define some values for these with the regular `--bg-gradient-xx: ...` syntax. On the `body` and `footer` I set `transition-property` and `transition-duration` to tell it which properties I want to animate: body { --background: fixed linear-gradient(var(--bg-gradient-top), var(--bg-gradient-mid) 80%); transition-property: --bg-gradient-top, --bg-gradient-mid; transition-duration: 0.5s; } footer { background: linear-gradient(oklch(0 0 0 / 0) 40%, var(--bg-gradient-bottom)); transition: --bg-gradient-bottom 0.5s; } And like motherflipping magic, the colours transition seamlessly into each other when the values change! I love CSS. The animation is such an unnecessary touch, but this is my website so unnecessary is the name of the game. ## Polyfilling Temporal for Safari Alas, Safari is behind the times. We love progressive enhancement, and of course I could have just removed any of the transition logic for people whose browsers don't support Temporal, but that's no fun. They deserve sunsets too! Writing a shim for Temporal was also no fun, but I did it because I love you. There are various Temporal polyfills around and about, but I didn't want to end up importing a whole lot of extra JS when I only needed one or two functions. I'm not using any kind of bundler on this site - I use Eleventy to generate the pages, but scripts are just imported vanilla - so I couldn't import something with NPM and expect it to tree-shake any bits I wasn't using. It was a lot more lightweight to just write my own. To check for Temporal support, it's a matter of just checking if `window.Temporal?.PlainTime` is undefined: const supportsTemporal = typeof window.Temporal?.PlainTime !== "undefined"; I'm checking for `PlainTime` specifically as some browsers may have very high level Temporal implementations, but we can't do much without `PlainTime`. To get the user's time in a non-Temporal world, we can just call the good old-fashioned `new Date()`: function getUserTime() { if (!supportsTemporal) { return new Date(); } return Temporal.Now.plainTimeISO(); } To compare dates, we do it by comparing epoch timestamps. These represent the number of milliseconds since the Unix epoch, 01 Jan 1970. export function jsDateCompare(date1, date2) { const date1Ms = date1.getTime(); const date2Ms = date2.getTime(); if (date1Ms === date2Ms) return 0; return date1Ms < date2Ms ? -1 : 1; } Then, we can just assign whichever version of the function we need: const compare = supportsTemporal ? Temporal.PlainTime.compare : jsDateCompare; To polyfill `until`, I've got a `durationBetween` function which will call `until` if Temporal's supported, otherwise it'll subtract two epoch timestamps, and divide the result by 1000 to get the duration as seconds: export function durationBetween(time1, time2) { if (!supportsTemporal) { return (time2.getTime() - time1.getTime()) / 1000; } return time1.until(time2); } Then I call it like this: case compare(timeNow, stages.sunset.start) >= 0 && compare(timeNow, stages.night.start) < 0: { currentStageName = "sunset"; timeUntilNextStage = durationBetween(timeNow, stages.night.start); break; } I wrote a whole suite of unit tests (for a PERSONAL project! I know!) to make sure behaviour was exactly the same, and it seems to be working nicely. I'm hoping I can remove the polyfills in time, but given that the web is beautifully backwards-compatible, it's not the end of the world if it stays around longer than it needs to. ## Fixing a weird background glitch in Safari SAFARI WHY. I started experiencing a very odd glitch in Safari for MacOS where the background gradient would only show up in the initial viewport - when you scrolled, it went white or black depending on whether it was light or dark mode. I narrowed it down to the `background-attachment: fixed` property of the body. After a lot of disabling random CSS and diffing against the `main` branch, which doesn't have that problem, I found out that it really doesn't play nicely with `container-type: inline-size`. In the course of redesigning the site, I'd added a new container context to the `<body>` element and in the process broken the gradient rendering for Safari, as something goes wrong when it tries to render the gradient background with a `fixed` attachment. Chrome, Firefox and iOS Safari were totally fine. When I half-jokingly said I'd have to find out what the modern equivalent of `<!--[IF IE]>` was, David Bushell pointed me to Eric Meyer's post about accessible table headers, which in turn led me to Browser Strangeness. That did indeed have a `@supports` query that targeted Safari for MacOS: @supports (not (-webkit-text-size-adjust:none)) and (font: -apple-system-body) { .selector { property:value; } } } I stuck a `position-attachment: initial` in there, and lo and behold, the problem went away. It means the background isn't quite how I wanted it to look in Safari, but I'll survive. ## This was surprisingly complex The individual moving parts of this project - getting the time and choosing colours, mixing the colours by percentages, animating the transitions - were not that complicated in isolation. Sure, they required me to learn things and look things up, but it was a fun thing to build (until the point where Safari came into the picture). The challenge came wiring it all together in a way that didn't cause flashes of unstyled content (the dreaded FOUC) or flashes of the wrong stage before we calculate the current time. This is a static site, so it's all client-side JS. Ideally I'd compute user's the current time on the server and serve the content with the correct colour values in the HTML, but my web host only supports static sites. To get around that I had to add another separate `init.js` script which runs instantly - it's got a bit of a copy and paste job going on with some of the functions, but it does a very rudimentary check of the user's current time and sets the stage accordingly with no transitions, just so there's _some_ styling on initial load. My JS is all modules, so is deferred by default. I experimented with making _all_ the JS render-blocking with `blocking="render"`, but that felt a bit gross and also didn't fix the FOUC in Firefox. But that's fine, y'know? It still loads in well under a second, and still looks good if you have JS disabled. It's my personal site and it doesn't need to be perfect.
013
Reposted by Mathew Attlee
Piccalilli @piccalilli.front-end.social.ap.brid.gy · 21/09/2026
🚨 Our huge 35% discount on all courses ends tomorrow! 🚨 Use the coupon code PRICEFALL at checkout. Don't miss out! piccalil.li/courses
Autumn sale, September 8th until September 22nd. 

35% off all courses. 

Save over £80 with code “PRICEFALL”
001
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 15/09/2026
Has anyone read any good analysis on why Anthropic boss Dario Amodei wants AI model development to slow down, and be regulated? What's the ulterior movement?
000
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 11/09/2026
Time to reconsider my use of Claude Code now that Anthropic might be building a Minority Report like system to monitor activists prospect.org/2026/09/09/anthropic-a…
prospect.org
Anthropic Is Building a Predictive Surveillance System to Monitor Activists
New hires and comments in interviews show that the AI giant is using its capabilities against dissenters. The post Anthropic Is Building a Predictive Surveillance System to Monitor Activists appeared first on The American Prospect.
001
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 15/08/2026
This article sums up my current bugbear with people using Claude, as its output is too verbose. I don't mind the use of agentic tools, though I want a concise explanation written by a human. vickiboykis.com/2026/08/12/write-fo…
vickiboykis.com
Write for people
Make it shorter.
001
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 08/08/2026
This article makes some quite good points about using agentic coding tools to experiment with different software architectures and ideas e.g. local-first, event sourcing etc www.iankduncan.com/engineering/2026…
iankduncan.com
Getting Freaky in the Age of AI - Ian Duncan
The only way to have a competitive edge in the age of AI is to be aggressively weird with what you build.
000
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 05/08/2026
When I stumble upon an interesting post, I check if the blog has an RSS feed, and if not contact them querying this. Fortunately, more often than not, particularly if they are a tech blog, they will write back and say they've add a feed. 😁🤓 #RSS
012
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 04/08/2026
I never studied formal methods at university but this article on their application in agentic coding is quite intriguing. annievella.com/posts/verification-w… #AICoding
annievella.com
Verification Without Inspection - Annie Vella
A week ago I finished up at Westpac NZ. I was fortunate to spend the last few years there as a Distinguished Engineer, a role with an unusually wide and undefined remit. It was the perfect playground for a curious mind, giving me the freedom to think deeply about all sorts of interesting questions. The trouble is that there are only so many hours in the day, and it’s never enough for all the curiosities tugging at my mind. So I made the difficult decision to leave so I could create more time, at least for a while, to scratch a few of those itches. This post focuses on the one that I’m most passionate about.
000
Reposted by Mathew Attlee
abadidea @0xabad1dea.infosec.exchange.ap.brid.gy · 31/07/2026
OpenAI: we put our evilest AI in a sandbox that did in fact have an internet connection but mediated through a proxy that was only supposed to allow downloading python junk. It circumvented the proxy and we failed to notice for FIVE DAYS that it was going on an interstate crime spree with the […]
infosec.exchange
Original post on infosec.exchange
522155
Reposted by Mathew Attlee
Jorijn Schrijvershof @jorijn.jorijn.com.ap.brid.gy · 28/07/2026
Today, I’m letting you know that toot.community will close permanently on **28 October 2026**. This decision is final, and the server won’t be handed over to anyone else. When I started running toot.community, I really enjoyed it. Over time, it became more stressful and less rewarding. Every […]
social.jorijn.com
Original post on social.jorijn.com
8143
Reposted by Mathew Attlee
Piccalilli @piccalilli.front-end.social.ap.brid.gy · 24/07/2026
Folks love it when we share indexes of cool stuff, so here's another! letsgetcreative.today
letsgetcreative.today
Let's Get Creative
A collection of high-quality, free, online creativity tools.
002
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 24/07/2026
Frontier models are still inventing package names 😵‍💫 socket.dev/blog/slopsquatting-targe… #AICoding
socket.dev
New Study Identifies 53 Slopsquatting Targets Across 5 Front...
Five frontier LLMs generated the same nonexistent package names, leaving 53 available for potential slopsquatting across PyPI and npm.
000
Reposted by Mathew Attlee
Niklas Korz @handle.invalid · 21/07/2026
RE: mastodon.social/@gamingonlinux/1169… So @mozilla shut down their own Mastodon instance, don''t post on their mastodon.social account anymore either, have no official Firefox presence on the Fediverse anymore (besides developer-focused accounts @firefoxwebdevs and […]
rheinneckar.social
Original post on rheinneckar.social
1014
Reposted by Mathew Attlee
calm.like.a.bomb @calm-bomb.metalhead.club.ap.brid.gy · 18/07/2026
Oh, WOW! I'm really impressed by this. Bandcamp implements subsonic/opensubsonic API so you can listen to your favorite band in your favorite client! I think this is a first for streaming services, right? #bandcamp #subsonic #opensubsonic #music #streaming […]
metalhead.club
Original post on metalhead.club
114
Reposted by Mathew Attlee
Eric Eggert @yatil.social · 15/07/2026
Stop using aria-label when your link/button already has an accessible name, doubly so when the content of the aria-label is just the same as the content of the link/button.
001
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 04/07/2026
I've just stumbled upon London Data Week, combing two things I love, which is happening next week! It's a shame that so many of the sessions are during the day when I'll be working. londondataweek.org #LondonDataWeek #LDW26
londondataweek.org
londondataweek.org
011
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 26/06/2026
Quite interesting post of the profitability of AI. The TLDR is inference is profitable, but they blow all their profits on training new models www.seangoedecke.com/ai-inference-i…
000
Reposted by Mathew Attlee
OpenTech(AUC) @opentech-auc.social.edu.nl.ap.brid.gy · 25/06/2026
To be shared with friends and loved ones: 1/5
On my socials, all I want is to live my best life and share it with my friends.

Character says: "Phone eats first" while taking a picture of the food on the table.

But shomehow, that's taken to mean I'm okay with my every move being tracked and turned into data.

How do I exist without selling myself to Big Tech?
106
Reposted by Mathew Attlee
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 25/06/2026
I agree that calling something AI generated or AI slop is a lazy form of criticism. 00f.net/2026/06/25/stop-calling-eve…
00f.net
Calling everything AI-generated is lazy
The new lazy comment’s “AI-generated”.
002
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 25/06/2026
I agree that calling something AI generated or AI slop is a lazy form of criticism. 00f.net/2026/06/25/stop-calling-eve…
00f.net
Calling everything AI-generated is lazy
The new lazy comment’s “AI-generated”.
002
Reposted by Mathew Attlee
Open Web Docs @openwebdocs.front-end.social.ap.brid.gy · 23/06/2026
We've completed our work on Web Security documentation on @mdn ! The entire MDN content tree has been reworked and now features in-depth information on: - Attacks - Defenses - Authentication - Threat Modeling ↪️ Blog post openwebdocs.org/content/posts/secur…
openwebdocs.org
Web Security docs on MDN
Open Web Docs supports web platform documentation for the benefit of web developers & designers worldwide. We are a community of web developers, standards makers, and technology companies that rely on this documentation as critical digital infrastructure, and we work cooperatively to ensure its long-term success and maintenance.
1616
Reposted by Mathew Attlee
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 16/06/2026
Turns out developers really hate AI generated blog posts. I know I find blog posts with AI generated images on the nose. writethatblog.substack.com/p/dev-re…
002
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 16/06/2026
Turns out developers really hate AI generated blog posts. I know I find blog posts with AI generated images on the nose. writethatblog.substack.com/p/dev-re…
002
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 08/06/2026
This is a fascinating read about the history of Waterfall, Agile and whether spec-driven development is Waterfall or something else. blog.herlein.com/post/is-waterfall-… #SpecDrivenDevelopment
blog.herlein.com
Is Waterfall Coming Back? Sort Of. Not Really. Both — And the Bigger Question Underneath. · Greg Herlein
000
Reposted by Mathew Attlee
BeaconDB @beacondb.mapstodon.space.ap.brid.gy · 08/06/2026
Big thank you to @yayacout for developing a new WiFi algorithm for BeaconDB, which has now finally been deployed! You should see much more accurate location estimates for WiFi, and if the data doesn't seem up to scratch, this new algorithm will improve estimates with new submissions. One major […]
mapstodon.space
Original post on mapstodon.space
027
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 06/06/2026
AI coding tools are very handy but they can come at a cost, so much so that you end up with situations where "no one on the team could explain why certain design decisions had been made, or how different parts of the system were supposed to work together" […]
hachyderm.io
Original post on hachyderm.io
020
Reposted by Mathew Attlee
Sean Coates @sean.scoat.es.ap.brid.gy · 03/06/2026
Devops, mid-2026:
The Daily Struggle / Two Buttons meme.
Left button: “Upgrade: new CVE!”
Right button: “Don’t upgrade: supply chain disaster!”
001
Reposted by Mathew Attlee
Pamela Fox @pamelafox.fosstodon.org.ap.brid.gy · 03/06/2026
Nice reflective post from @nzakas : "What we lose when we stop coding" newsletter.humanwhocodes.com/posts/… He cautions against over-reliance on AI coding agents for 100% of tasks and suggests spending a short daily session on unassisted coding each day.
newsletter.humanwhocodes.com
What we lose when we stop coding
001
Reposted by Mathew Attlee
Terence Eden @edent.mastodon.social.ap.brid.gy · 02/06/2026
🆕 blog! “Using FourSquare's API to post location checkins to social media” What is this, 2016? I like sharing my location with my pocket friends sometimes. If I'm in a cool bar that they know, perhaps they can recommend a drink. If they live nearby, maybe they want to come for dinner. Not […]
mastodon.social
Original post on mastodon.social
011
Reposted by Mathew Attlee
Niki @nikitonsky.mastodon.online.ap.brid.gy · 28/05/2026
1.8 GB per emoji
macOS Tahoe 26.5 update notice, weighting 14.45 GB with comment that it adds 8 new emoji
104795
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 27/05/2026
Has anyone switched from lint-staged to nano-staged? Apparently the latter is much faster github.com/usmanyunusov/nano-staged
github.com
GitHub - usmanyunusov/nano-staged: Tiny tool to run commands for modified, staged, and committed files in a GIT repository.
Tiny tool to run commands for modified, staged, and committed files in a GIT repository. - usmanyunusov/nano-staged
000
Reposted by Mathew Attlee
Andrew Nesbitt @andrewnez.mastodon.social.ap.brid.gy · 23/05/2026
Updated my dependency cooldown post with all the ongoing work to enable cooldown features in various ecosystems: nesbitt.io/2026/03/04/package-manag…
nesbitt.io
Package Managers Need to Cool Down
This post was requested by Seth Larson, who asked if I could do a breakdown of dependency cooldowns across package managers. His framing: all tools should support a globally-configurable `exclude-newer-than=<relative duration>` like `7d`, to bring the response times for autonomous exploitation back into the realm of human intervention. When an attacker compromises a maintainer’s credentials or takes over a dormant package, they publish a malicious version and wait for automated tooling to pull it into thousands of projects before anyone notices. William Woodruff made the case for dependency cooldowns in November 2025, then followed up with a redux a month later: don’t install a package version until it’s been on the registry for some minimum period, giving the community and security vendors time to flag problems before your build pulls them in. Of the ten supply chain attacks he examined, eight had windows of opportunity under a week, so even a modest cooldown of seven days would have blocked most of them from reaching end users. The concept goes by different names depending on the tool (`cooldown`, `minimumReleaseAge`, `stabilityDays`, `exclude-newer`) and implementations vary in whether they use rolling durations or absolute timestamps, whether they cover transitive dependencies or just direct ones, and whether security updates are exempt. But the adoption over the past year has been remarkably fast. ### JavaScript The JavaScript ecosystem moved on this faster than anyone else, with pnpm shipping `minimumReleaseAge` in version 10.16 in September 2025, covering both direct and transitive dependencies with a `minimumReleaseAgeExclude` list for packages you trust enough to skip. Yarn shipped `npmMinimalAgeGate` in version 4.10.0 the same month (also in minutes, with `npmPreapprovedPackages` for exemptions), then Bun added `minimumReleaseAge` in version 1.3 in October 2025 via `bunfig.toml`. npm took longer but shipped `min-release-age` in version 11.10.0 in February 2026. Deno has `--minimum-dependency-age` for `deno update` and `deno outdated`. Five package managers in six months, which I can’t think of a precedent for in terms of coordinated feature adoption across competing tools. ### Python uv has had `--exclude-newer` for absolute timestamps since early on and added relative duration support (e.g. `1 week`, `30 days`) in version 0.9.17 in December 2025, along with per-package overrides via `exclude-newer-package`. pip shipped `--uploaded-prior-to` in version 26.0 in January 2026, though it only accepts absolute timestamps and there’s an open issue about adding relative duration support. ### Ruby Bundler and RubyGems have no native cooldown support, but gem.coop, a community-run gem server, launched a cooldowns beta that enforces a 48-hour delay on newly published gems served from a separate endpoint. Pushing the cooldown to the index level rather than the client is interesting because any Bundler user pointed at the gem.coop endpoint gets cooldowns without changing their tooling or workflow at all. ### Rust, Go, PHP, .NET Cargo has an RFC in progress and the registry-side infrastructure for cooldowns is stabilized in Cargo 1.94 (releasing March 5, 2026). Their approach sidesteps the exemption list problem entirely: instead of exempting packages from cooldowns, you explicitly opt in to a new version with `cargo update foo --precise 1.5.10`, which records the choice in your lockfile. No exclude list to remember to clean up later. In the meantime there’s also cargo-cooldown, a third-party wrapper that enforces a configurable cooldown window on developer machines as a proof-of-concept. Go has an open proposal for `go get` and `go mod tidy`, Composer has two open issues, and NuGet has an open issue though .NET projects using Dependabot already get cooldowns on the update bot side since Dependabot expanded NuGet support in July 2025. ### Dependency update tools Renovate has had `minimumReleaseAge` (originally called `stabilityDays`) for years, long before the rest of the ecosystem caught on, adding a “pending” status check to update branches until the configured time has passed. Mend Renovate 42 went a step further and made a 3-day minimum release age the default for npm packages in their “best practices” config via the `security:minimumReleaseAgeNpm` preset, making cooldowns opt-out rather than opt-in for their users. Dependabot shipped cooldowns in July 2025 with a `cooldown` block in `dependabot.yml` supporting `default-days` and per-semver-level overrides (`semver-major-days`, `semver-minor-days`, `semver-patch-days`), with security updates bypassing the cooldown. Snyk takes the most aggressive stance with a built-in non-configurable 21-day cooldown on automatic upgrade PRs. npm-check-updates added a `--cooldown` parameter that accepts duration suffixes like `7d` or `12h`. ### Checking your config zizmor added a `dependabot-cooldown` audit rule in version 1.15.0 that flags Dependabot configs missing cooldown settings or with insufficient cooldown periods (default threshold: 7 days), with auto-fix support. StepSecurity offers a GitHub PR check that fails PRs introducing npm packages released within a configurable cooldown period. OpenRewrite has an `AddDependabotCooldown` recipe for automatically adding cooldown sections to Dependabot config files. For GitHub Actions specifically, pinact added a `--min-age` flag, and prek (a Rust reimplementation of pre-commit) added `--cooldown-days`. ### Still waiting For Go, Bundler, Composer, and pip, cooldown support is still in discussion or only partially landed, which means you’re relying on Dependabot or Renovate to enforce the delay. That covers automated updates, but nothing stops someone from running `bundle update` or `go get` locally and pulling in a version that’s been on the registry for ten minutes. I couldn’t find any cooldown discussion at all for Maven, Gradle, Swift Package Manager, Dart’s pub, or Elixir’s Hex, if you know of one, let me know and I’ll update this post. The feature also goes by at least ten different configuration names across the tools that do support it (`cooldown`, `minimumReleaseAge`, `min-release-age`, `npmMinimalAgeGate`, `exclude-newer`, `stabilityDays`, `uploaded-prior-to`, `min-age`, `cooldown-days`, `minimum-dependency-age`), which makes writing about it almost as hard as configuring it across a polyglot project. ### Language vs. system package managers On npm, PyPI, and RubyGems, running `npm publish` or `gem push` makes a package installable worldwide in seconds, and if Dependabot or Renovate happens to run in that window, the malicious code lands in a project without a human ever seeing it. All of the supply chain attacks William examined exploit this property, where publishing and distribution are the same act and nothing stands between a compromised maintainer account and thousands of downstream projects. System package managers work differently because they separate those two things. When someone pushes a new version of an upstream library, it doesn’t appear in `apt install` or `brew install` until a distribution maintainer has reviewed the change, updated the package definition, and pushed it through a build pipeline. Fedora packages go through review and koji builds, Homebrew requires a pull request that passes CI and gets merged by a maintainer. A compromised upstream tarball still has to survive that process before it reaches anyone’s machine, and the people doing the reviews tend to notice when a patch adds an obfuscated postinstall script that curls a remote payload. Debian goes further. Even if a maintainer account is compromised, uploads land in unstable first, then automigrate to testing after 2 to 10 days depending on urgency and availability of package tests. Stable only gets updates through a separate release process. That’s effectively a built-in cooldown with human review at multiple stages. Cooldowns on the language package manager side are trying to retrofit something like that review window onto ecosystems that never had one, giving security researchers a few days to flag a malicious publish before automated tooling pulls it into lockfiles. Asking Homebrew or apt to add the same feature would mean delaying security patches through a process that already has human gatekeepers, which costs more than it saves. ### The timestamp problem pip’s `--uploaded-prior-to` and npm’s older `--before` flag both take absolute timestamps, and the discussion about adding relative duration support to pip reveals how these two modes serve different goals that happen to share implementation surface. An absolute timestamp pins your dependency resolution to a moment in time, so running the same install six months from now produces the same result, which is a reproducibility feature. A relative duration like `7 days` creates a sliding window that moves forward with you, so you always exclude recently published packages regardless of when you run the build, which is a security feature. uv’s `--exclude-newer` accepts both forms, and npm has both `--before` for absolute dates and `min-release-age` for relative durations. pnpm, Yarn, Bun, and Deno only accept relative durations. The pip thread also gets into the surprisingly fiddly business of parsing duration strings. ISO 8601 durations (`P7D`) are unambiguous but nobody wants to type them, human-readable strings like `7 days` are friendly but need a parser that pip’s maintainers would rather not write and maintain, and variable-length calendar units like months and years require knowing which month you’re in to convert to a concrete number of days. uv went with ISO 8601 plus friendly strings but excluded months and years entirely, and pip’s maintainers are leaning toward just accepting a bare number of days, which covers nearly every real use case without dragging in leap year arithmetic. Even the question of what “seven days ago” means gets complicated when your CI server is in UTC, your developer laptop is in US Pacific time, and the registry timestamp uses whatever timezone PyPI’s servers happen to be configured with. A few hours of timezone drift can determine whether a package published six days and twenty-two hours ago passes the cooldown check or not.
001
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 23/05/2026
Turns out that Palantir's tech platform is "slow and clunky" with a "poor user experience" democracyforsale.substack.com/p/rev… #Palantir
003
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 21/05/2026
If one sentence sums up this article, for me it’s “remove the unhealthy inclination to maximize productivity at every moment” evilmartians.com/chronicles/ai-assi… #AICoding
000
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 19/05/2026
This is quite an interesting read talking about the knowledge that the best developers have in their heads, which isn't captured in code or documentation, and the challenges that creates when working with AI agents. The key problem is agents can’t learn, they are like pairing with Leonard Shelby […]
hachyderm.io
Original post on hachyderm.io
000
Reposted by Mathew Attlee
Terence Eden @edent.mastodon.social.ap.brid.gy · 17/05/2026
🆕 blog! “GDS weighs in on the NHS's decision to retreat from Open Source” Within the UK's Civil Service you occasionally hear the expression "being invited to a meeting without biscuits". It implies a rather frosty discussion without any of the polite niceties of a normal meeting. In general […]
mastodon.social
Original post on mastodon.social
2316
Reposted by Mathew Attlee
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 13/05/2026
This behaviour sounds a lot like addiction. It has been argued that AI coding tools may trigger dopamine loops. www.businessinsider.com/coders-keep… #AICoding
001
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 13/05/2026
I find the @alternativeto crew picks a great way to find about new apps, particularly open-source ones. Does anyone know of blogs that highlight new apps? alternativeto.net/lists/11/crew-pic…
001
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 13/05/2026
This behaviour sounds a lot like addiction. It has been argued that AI coding tools may trigger dopamine loops. www.businessinsider.com/coders-keep… #AICoding
001
Mathew Attlee @codeinabox.hachyderm.io.ap.brid.gy · 12/05/2026
@hackaday have you come across any DIY dog trackers? I currently own a PitPat GPS tracker, however the GPS uses up battery, and doesn't work well indoors. In theory a DIY tracker could leverage @beacondb, which would use less battery than GPS.
000
Reposted by Mathew Attlee
daniel:// stenberg:// @bagder.mastodon.social.ap.brid.gy · 12/05/2026
I like the Registers headline: "Anthropic’s bug-hunting Mythos was greatest marketing stunt ever, says cURL creator" ... even though I did not say that. 😂 www.theregister.com/security/2026/0…
theregister.com
Anthropic’s bug-hunting Mythos was greatest marketing stunt ever, says cURL creator
After all that hype, AI scanner found one low-severity cURL flaw
2316
Reposted by Mathew Attlee
daniel:// stenberg:// @bagder.mastodon.social.ap.brid.gy · 11/05/2026
#Mythos finds a #curl vulnerability yes, as in singular one. daniel.haxx.se/blog/2026/05/11/myth…
daniel.haxx.se
Mythos finds a curl vulnerability
yes, as in singular _one_. Back in April 2026 Anthropic caused a lot of media noise when they concluded that their new AI model _Mythos_ is _dangerously good_ at finding security flaws in source code. Apparently Mythos was so good at this that Anthropic would not release this model to the public yet but instead trickle it out to a selected few companies for a while to allow a few good ones(?) to get a head start and fix the most pressing problems first, before the general populace would get their hands on it. The whole world seemed to lose its marbles. Is this the end of the world as we know it? An amazingly successful marketing stunt for sure. ## My (non-) access Part of the deal with _project Glasswing _was that Anthropic also offered access to their latest AI model to “Open Source projects” via Linux Foundation. Linux Foundation let their project Alpha Omega handle this part, and I was contacted by their representatives. As lead developer of curl I was offered access to the magic model and I graciously accepted the offer. Sure, I’d like to see what it can find in curl. I signed the contract for getting access, but then nothing happened. Weeks went past and I was told there was a hiccup somewhere and access was delayed. Eventually, I was instead offered that someone else, who has access to the model, could run a scan and analysis on curl for me using Mythos and send me a report. To me, the distinction isn’t that important. It’s not that I would have a lot of time to explore lots of different prompts and doing deep dive adventures anyway. Getting the tool to generate a first proper scan and analysis would be great, whoever did it. I happily accepted this offer. (I am purposely leaving out the identity of the individual(s) involved in getting the curl analysis done as it is not the point of this blog post.) ## AI scans of curl Before this first Mythos report, we had already scanned curl with several different very capable AI powered tools (I mean _in addition to_ running a number of “normal” static code analyzers all the time, using the pickiest compiler options and doing fuzzing on it for years etc). Primarily AISLE, Zeropath and OpenAI’s Codex Security have been used to scrutinize the code with AI. These tools and the analyses they have done have triggered somewhere between _two and three hundred_ bugfixes merged in curl through-out the recent 8-10 months or so. A bunch of the findings these AI tools reported were confirmed vulnerabilities and have been published as CVEs. Probably a dozen or more. Nowadays we also use tools like GitHub’s Copilot and Augment code to review pull requests, and their remarks and complaints help us to land better code and avoid merging new bugs. I mean, we still merge bugs of course but the PR review bots regularly highlight issues that we fix: our merges would be worse without them. The AI reviews are used _in addition_ to the human reviews. They help us, they don’t replace us. We also see a high volume of high quality security reports flooding in: security researchers now use AI extensively and effectively. Security is a _top_ _priority_ for us in the curl project. We follow every guideline and we do software engineering properly, to reduce the number of flaws in code. Scanning for flaws is just one of many steps to keep this ship safe. You need to search long and hard to find another software project that makes as much or goes further than curl, for software security. Steps involved in keeping curl secure ## May 6, 2026 It was with great anticipation we received the first source code analysis report generated with Mythos. Another chance for us to find areas to improve and bugs to fix. To make an even better curl. This initial scan was made on curl’s git repository and its master branch of a certain recent commit. It counted 178K lines of code analyzed in the src/ and lib/ subdirectories. The analysis details several different approaches and methods it has performed the search, and how it has focused on trying to find which flaws. A fun note in the top of the report says: > curl is one of the most fuzzed and audited C codebases in existence (OSS-Fuzz, Coverity, CodeQL, multiple paid audits). Finding anything in the hot paths (HTTP/1, TLS, URL parsing core) is unlikely. … and it correctly found no problems in those areas. Completely unscientific poll on Mastodon about people’s expectations for Mythos scanning curl ## The size of curl curl is currently 176,000 lines of C code when we exclude blank lines. The source code consists of 660,000 words, which is 12% more words than the entire English edition of the novel War and Piece. On average, every single production source code line of curl has been written (and then rewritten) 4.14 times. We have polished on this. Right now, the existing production code in git master that still remains, has been authored by 573 separate individuals. Over time, a total of 1,465 individuals have so far had their proposed changes merged into curl’s git repository. We have published 188 CVEs for curl up until now. curl is installed in over _twenty million instances_. It runs on over _110 operating systems_ and _28 CPU architectures_. It runs in every smart phone, tablet, car, TV, game console and server on earth. ## Five findings became one The report concluded it found **five** “Confirmed security vulnerabilities”. I think using the term _confirmed_ is a little amusing when the AI says it confidently by itself. Yes, the AI thinks they are confirmed, but the curl security team has a slightly different take. Five issues felt like nothing as we had expected an extensive list. Once my curl security team fellows and I had poked on the this short list for a number of hours and dug into the details, we had trimmed the list down and were left with _one_ confirmed vulnerability. The other four were three false positives (they highlighted shortcomings that are documented in API documentation) and the fourth we deemed “just a bug”. The single confirmed vulnerability is going to end up a _severity low_ CVE planned to get published in sync with our pending next curl release 8.21.0 in late June. The flaw is not going to make anyone grasp for breath. All details of that vulnerability will of course not get public before then, so you need to hold out for details on that. The Mythos report on curl also contained a number of spotted bugs that it concluded were not vulnerabilities, much like any new code analyzer does when you run it on hundreds of thousands of lines of code. All the bugs in the report are being investigated and one bye one we are fixing those that we agree with. All in all about twenty bugs that are described and explained very nicely. Barely any false positives, so I presume they have had a rather high threshold for certainty. curl is certainly getting better thanks to this report, but counted by the volume of issues found, all the previous AI tools we have used have resulted in larger bugfix amounts. This is only natural of course since the first tools we ran had many more and easier bugs to find. As we have fixed issues along the way, finding new ones are slowly becoming harder. Additionally, a bug can be small or big so it’s not always fair to just compare numbers ## Not particularly “dangerous” My personal conclusion can however not end up with anything else than that the big hype around this model so far was primarily marketing. I see no evidence that this setup finds issues to any particular higher or more advanced degree than the other tools have done before Mythos. Maybe this model is a little bit better, but even if it is, it is not better to a degree that seems to make a significant dent in code analyzing. This is just _one_ source code repository and maybe it is much better on other things. I can only tell and comment on what it found here. ## Still very good But allow me to highlight and reiterate what I have said before: AI powered code analyzers are _significantly_ better at finding security flaws and mistakes in source code than any traditional code analyzers did in the past. All modern AI models are good at this now. Anyone with time and some experimental spirits can find security problems now. The high quality chaos is real. Any project that has not scanned their source code with AI powered tooling will likely find huge number of flaws, bugs and possible vulnerabilities with this new generation of tools. Mythos will, and so will many of the others. Not using AI code analyzers in your project means that you leave adversaries and attackers time and opportunity to find and exploit the flaws you don’t find. ## How AI analyzers differ * They can spot when the comment says something about the code and then conclude that the code does not work as the comment says. * It can check code for platforms and configurations we otherwise cannot run analyzers for * It “knows” details about 3rd party libraries and their APIs so it can detect abuse or bad assumptions. * It “knows” details about protocols curl implements and can question details in the code that seem to violate or contract protocol specifications * They are typically good at summarizing and explaining the flaw, something which can be rather tedious and difficult with old style analyzers. * They can often generate and offer a patch for its found issue (even if the patch usually is not a 100% fix). ## More details from the report **Zero memory-safety vulnerabilities found.** Methodology note: this review is hand-driven analysis using LLM subagents for parallel file reads, with every candidate finding re-verified by direct source inspection in the main session before being recorded. The CVE to variant-hunt mapping was built from curl’s own vuln.json. No automated SAST tooling was used. This outcome is consistent with curl’s status as one of the most heavily fuzzed and audited C codebases. The defensive infrastructure (capped dynbufs everywhere, `curlx_str_number` with explicit max on every numeric parse, `curlx_memdup0` overflow guard, CURL_PRINTF format-string enforcement, per-protocol response-size caps, pingpong 64KB line cap) systematically closes the bug classes that would normally be productive in a codebase this size. Coverage now includes: all minor protocols, all file parsers, all TLS backends’ verify paths, http/1/2/3, ftp full depth, mprintf, x509asn1, doh, all auth mechanisms, content encoding, connection reuse, session cache, CLI tool, platform-specific code, and CI/build supply chain. ## AI finds existing kinds of errors It should be noted that the AI tools find the usual and established kind of errors we already know about. It just finds new instances of them. We have not seen any AI so far report a vulnerability that would somehow be of a novel kind or something totally new. They do not reinvent the field in that way, but they do dig up more issues than any other tools did before. ## More to find These were absolutely not the last bugs to find or report. Just while I was writing the drafts for this blog post we have received more reports from security researchers about suspected problems. The AI tools will improve further and the researchers can find new and different ways to prompt the existing AIs to make them find more. We have not reached the end of this yet. I hope we can keep getting more curl scans done with Mythos and other AIs, over and over until they truly stop finding new problems. ## Credits Thanks to Anthropic and Alpha Omega for providing the model, the tools and doing the scan for us. Thanks also to the individual who did the scan for us. Much appreciated! Top image by Jin Kim from Pixabay Thanks for flying curl. It’s never dull.
7247121
Reposted by Mathew Attlee
Richard MacManus @ricmac.mastodon.social.ap.brid.gy · 09/05/2026
Now they’ve discovered external style sheets.
Screenshot of X discussion about linking to a CSS file so the LLM company doesn’t charge you more money for rendering HTML
12346