<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Aiden Vaines</title>
    <description>The latest articles on Forem by Aiden Vaines (@avaines).</description>
    <link>https://forem.com/avaines</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3839986%2Fa182c755-5cbd-4950-9c91-b29c7f472f8e.jpeg</url>
      <title>Forem: Aiden Vaines</title>
      <link>https://forem.com/avaines</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/avaines"/>
    <language>en</language>
    <item>
      <title>¡Hola, soy DORA. Why hasn’t AI improved my metrics?</title>
      <dc:creator>Aiden Vaines</dc:creator>
      <pubDate>Sun, 10 May 2026 20:58:36 +0000</pubDate>
      <link>https://forem.com/avaines/hola-soy-dora-why-hasnt-ai-improved-my-metrics-2cod</link>
      <guid>https://forem.com/avaines/hola-soy-dora-why-hasnt-ai-improved-my-metrics-2cod</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published at &lt;a href="https://www.vaines.org/posts/2026-05-09-why-hasnt-ai-improved-my-metrics/" rel="noopener noreferrer"&gt;https://www.vaines.org/posts/2026-05-09-why-hasnt-ai-improved-my-metrics/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'm often asked about AI stuff as the rest of my blog might suggest. The world is currently scrambling around for how and where AI best accelerates delivery of software programmes, but I still don't think there is one solution - similar to what happens when you ask any two people how JIRA should be used to be fair.&lt;/p&gt;

&lt;p&gt;There's so much hype and a lot of vapour-thought for ways of working that sound legit but have never been battle tested at any scale. Intermixed with that are some amazing success stories and methodologies that work great for a a particular org or project or just a single team greatly enhancing their workflows.&lt;/p&gt;

&lt;p&gt;A team I'm working with have been delivering code - &lt;em&gt;yes, into production&lt;/em&gt; - for a little while and I'm seeing a pattern emerging from elsewhere in my programmes alongside those my peers work on doing similar AI acceleration journeys.&lt;/p&gt;

&lt;p&gt;Engineers are reporting they are shipping code faster, the tools are being used regularly and they are mostly liked. Qualitative measures like &lt;a href="https://getdx.com/blog/space-metrics/" rel="noopener noreferrer"&gt;SPACE&lt;/a&gt; show things improving and moving quickly but the quantitative measures like DORA, the entrenched way to measure how things are moving...haven't moved. In some cases they've reportedly got worse.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;DORA Metric&lt;/th&gt;
&lt;th&gt;Change&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Deployment Frequency&lt;/td&gt;
&lt;td&gt;➖&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lead Time For Change&lt;/td&gt;
&lt;td&gt;➖&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time to Restore Service&lt;/td&gt;
&lt;td&gt;➖&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Change Failure&lt;/td&gt;
&lt;td&gt;🔻&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;On the surface this is an uncomfortable place to be. AI is the second coming of Jesus if you believe the hype, so why doesn't it &lt;em&gt;make numbers go up&lt;/em&gt;? Engineers reckon they’re faster and stuff is going out faster for the most part - &lt;a href="https://arxiv.org/abs/2507.09089" rel="noopener noreferrer"&gt;yes I know all about the '19% study slower'&lt;/a&gt; - but all the measures we use, rely on, report on, and optimise for haven't changed positively or resoundingly.&lt;/p&gt;

&lt;h2&gt;
  
  
  DORA cares not for your AI tools
&lt;/h2&gt;

&lt;p&gt;DORA doesn’t care how quickly code appears on a screen. It cares how reliably and smoothly changes make it to production. Roughly that should include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
    A[Planning and Refinement] --&amp;gt; B[Coding]
    B --&amp;gt; C[Review]
    C --&amp;gt;|Changes required| B
    C --&amp;gt;|Approved| D[Testing and Validation]
    D --&amp;gt;|Defects found| B
    D --&amp;gt;|Validated| E[Deployment and Release]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you use AI automation like SpecKit, BMAD, or similar tooling, you take away some of the human bashing at the keyboard or poking and prodding at a handful of Claude/Copilot/Codex (why are they all C nouns?) terminals. The focus heavily switches from writing code to writing specifications, capturing and refining requirements and validating decisions. On the other side of the code generation task it's reviewing, criticising, and mobbing on a PR.&lt;/p&gt;

&lt;p&gt;It's not unreasonable to say that AI generates more fluff than most meat-developers do and it does take longer to properly go through, trim, redirect and refactor AI output. Even if the AI is doing the heavy lifting, and it does it faster than us mere mortals can, it needs iterating, checking and validating just like if humans wrote the code. There are decisions and choices in how it's built things, weird variable name choices, there's 300 tests which all pass.....because they are doing the equivalent &lt;code&gt;Assert True&lt;/code&gt; . Ultimately you're responsible for the code you commit, even if you effectively outsourced it to a robot.&lt;/p&gt;

&lt;p&gt;AI applies pressure at a single stage; code generation. There's now more work entering the system, our review capacity, CI/CD throughput, release governance, and risk tolerances largely all stay where they are. But the system is processing work at roughly the same rate, we're just tackling things larger than the old limits imposed by the bottleneck of us lazy humans limited by sleep, caffeine, and roughly 10 fingers.&lt;/p&gt;

&lt;p&gt;Sizing of work becomes a bit of a weird space too. Before you start measuring your deployments, how do you estimate a piece of work? Yes, you know roughly how you might tackle it, maybe you've got a rough plan in your head of where in the codebase it touches, how you might test it and so on. But you're not hands-on writing the code, you'll be drawing up specifications and requirements. Code generation is being handed off to an LLM to generate the code. You want to assume like you would with you human peers, it's having a good day and doesn't fall down rabbit holes, but the reviews and subsequent re-generations still take time.&lt;/p&gt;

&lt;p&gt;If you imagine any old 3-point story that includes an amount of writing some code but apply a SpecKit style AI workflow to it, the code is going to be almost entirely AI generated. You're likely to end up with more code to review, more edge cases through AI non-determinism. You then need to take the time you may have spent writing the code writing an implicit scope or contract spec to hand to the AI.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;On the determinism statement; I've heard this as a detractor statement for AI code generation quite a bit. I think if you asked any two developers, or the same developer a month apart, to write the same thing from the same information you would get two different results anyway as humans aren't deterministic either. I usually describe AI as being a cupboard of junior engineers. You chuck solid requirements in, you should get something working out but if you put crap in you get crap out. AI is the same, just each conversation (session) is a new engineer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once you've handed the specs for your theoretical 3-pointer over to the magic box of &lt;a href="https://openai.com/index/where-the-goblins-came-from/" rel="noopener noreferrer"&gt;goblins&lt;/a&gt; and performed your favourite ritual of computation; slaughter a couple of goats, scroll through &lt;a href="https://news.ycombinator.com/" rel="noopener noreferrer"&gt;hackernews&lt;/a&gt;, whatever. Then you look at what the magic box has produced and hope it's good or at least close. DORA assumes relatively stable units of work but the assumption starts to wobble a bit when you hit review phase and the code produced is poor quality, missed the target or perhaps is totally broken and you need to stretch the metaphor and kick the box of goblins a bit.&lt;/p&gt;

&lt;p&gt;You can now either re-run the code generation phase, hope Jupiter is in retrograde, and hope the result is closer to the expectation. If where AI went wrong is clear, you may be able to revisit the Spec and correct the problem before re-generating. If the code was close enough you might be able to steer it back into line or over the final hurdle. Whichever path gets taken is something we now need to measure. The measures for DORA might cover some of these activities but it's not going to surface the time back and forth and the struggle or pain points with the process. If the metrics are not providing feedback for improvement, what's the point?&lt;/p&gt;

&lt;h3&gt;
  
  
  What are we actually measuring?
&lt;/h3&gt;

&lt;p&gt;I started trying to think over what I'm actually using my metrics for, how they inform decisions, and where it made most sense to recalibrate given the changes in the approach. I think the question I'm trying to answer is 'what makes sense to track to get the same signals?' given the shift of effort left and right towards planning and review, away from the classic development task.&lt;/p&gt;

&lt;p&gt;Before AI driven development workflows (excluding review fix feedback loops) I imagined it looked, in its extreme like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
  A["Idea"] --&amp;gt; B["Slow Coding"]
  B --&amp;gt; C["Review"]
  C --&amp;gt; D["Deploy"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With AI driven development, we push the effort left and right away from the code generation task.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
  A["Idea"] --&amp;gt; B["Slow Refinement"]
  B --&amp;gt; C["Fast Coding"]
  C --&amp;gt; D["Slow Review"]
  D --&amp;gt; E["Deploy"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The overall amount of 'stuff' getting done hasn't really changed anywhere, just where it's being done, and how it's carved up has changed. The bottlenecks on how much can be done in a single unit of effort/work are quite different too. We're still reporting and recording DORA metrics I just needs to measure different tasks and activities underneath them.&lt;/p&gt;

&lt;p&gt;AI driven development task has lead us to, generally, larger, denser changes. It's easier to identify and scope tasks which previously you'd have carved up in to smaller tasks because, well....it's not you doing it.&lt;/p&gt;

&lt;p&gt;I find I tend to think in units of 'delivered features' rather than what makes sense to develop specifically like I would in a more traditional capacity. Not because I'm not doing the work as I jest, but because it's moving from thinking in a 'doing' mindset in to more 'product' focus. For years as engineering types, we've felt like product and delivery people don't always understand why something can't be split into multiple tasks or divided in a certain way and .... oh no... I owe some people some apologies.&lt;/p&gt;

&lt;p&gt;This trend towards larger units of work has a knock-on effect of bigger review effort, higher cognitive load for reviewers, and potentially a bigger failure surface. I thought the system/workflow might absorb the gains as additional scrutiny rather than expressing it as higher throughput. Which to some extent it has.&lt;/p&gt;

&lt;p&gt;When we're reviewing this work, the team are mobbing on the review tasks - &lt;em&gt;we used to call this pair-programming in the olden days&lt;/em&gt;. That's leading to our less senior team members better understanding what's going on, though I don't think this is as useful for learning as making mistakes and solving problems yourself. It helps with quorum for decision making and generally everyone actually having a good understanding of the system and generated code context. It is too early to really know what any of the long term impact of any of that is going to be.&lt;/p&gt;

&lt;p&gt;I &lt;a href="https://arxiv.org/abs/2507.00788" rel="noopener noreferrer"&gt;read a study a couple of weeks ago&lt;/a&gt;  where 150 or so professional developers were asked to write new features for a Java app, or expand its existing feature set with and without AI. They found task completion time improved by 30-50% with no overall change in code maintainability. Though there does seem to be a new study like this every five-minutes and I'm never sure who actually funded them. Scepticism aside, that does seem interesting that the previous generation of similar studies finding worse code and worse results. Have models got better? Are we more accepting of slop? Are we getting better at steering AI for our goals?&lt;/p&gt;

&lt;h3&gt;
  
  
  History doesn't repeat but it does have four legs and barks
&lt;/h3&gt;

&lt;p&gt;Manufacturing ran into similar problems like this decades ago; I've never worked in Manufacturing but Gene Kim et.al promised me in &lt;a href="https://amzn.to/3PsgsvE" rel="noopener noreferrer"&gt;The Phoenix Project&lt;/a&gt; that they did.&lt;/p&gt;

&lt;p&gt;Speeding up one stage doesn’t improve overall throughput unless all the bottlenecks move too, otherwise you just move the bottleneck. I think for this simplified SDLC example problem there are two main competing parts;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cycle time:&lt;/strong&gt; aka how long a piece of work takes. &lt;a href="https://martinfowler.com/bliki/CycleTime.html" rel="noopener noreferrer"&gt;Martin Fowler has a better explanation that I would ever write&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Throughput&lt;/strong&gt;: how much the system delivers or can be processed by the system.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The AI development workflows compress parts of cycle time though throughput continues with a slightly different set of constraints or bottlenecks imposed by the front-loading and backloading of effort to refinement and review phases.&lt;/p&gt;

&lt;p&gt;DORA metrics are of course not the only way you can measure things in the traditional SDLC and general software development spaces. My favourites or at the very least the four I have some actual experience and exposure to are;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cycle time variants,&lt;/strong&gt; basically measuring where time is spent, not just the total.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://queue.acm.org/detail.cfm?id=3454124" rel="noopener noreferrer"&gt;SPACE&lt;/a&gt;&lt;/strong&gt; adds satisfaction, communication, and activity to broaden the view, is more focused on a qualitative, I often describe SPACE as a vibes based alternative to DORA's hard measurements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://queue.acm.org/detail.cfm?id=3595878" rel="noopener noreferrer"&gt;DevEx&lt;/a&gt;&lt;/strong&gt; focuses on feedback loops, cognitive load, and flow.It comes from the same people who wrote SPACE, and is more focused, as the name suggests, on the Developer Experience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://getdx.com/research/measuring-developer-productivity-with-the-dx-core-4/" rel="noopener noreferrer"&gt;DX Core 4&lt;/a&gt;&lt;/strong&gt; tries to reconcile measures into speed, effectiveness, quality, and business impact. This is the only one of the list which at least acknowledges AI as a factor in modern development&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From a certain height with a bit of a squint they are all trying to surface out similar useful information, I think it can all boil down to asking "How long does it take to do stuff?" and "How hard is it to do it?", essentially identifying where lifecycle &lt;em&gt;friction&lt;/em&gt; exists. AI seems to just be adding a different type of friction which needs a highlighting without listening to the AI-token-hocking vendors who are profit incentivised to sell more tokens rather than useful implementations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which looks better ; 👓.....or 🕶️. 👓.......or 🕶️
&lt;/h3&gt;

&lt;p&gt;In most projects, DORA is already being derived from the existing toolchain. Jira tracks state transitions, commits reference tickets, and CI/CD systems mark deployments. Lead time is often calculated as something like “In Progress → Deployed” or “In Progress → Closed” and that's cool, we should continue to do so but we'll need make sure our measures account for the changes in how work is fed into the system for AI based working patterns.&lt;/p&gt;

&lt;p&gt;Instead of reducing everything to a single lead time number, we'll need to keep more of the intermediate signals and derive some additional ones from the same data. By that I means, if you already have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Jira issue transitions (e.g. In Progress, In Review, Done)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Git commits linked via ticket IDs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pull request timestamps&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CI/CD deployment events&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Given the existing data we can pull out these three extra measures which I think should give the extra information to make what we showing previously under the same DORA sauce.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Review latency (from Git)
&lt;/h4&gt;

&lt;p&gt;You’re likely already collecting PR data implicitly for current measures, just instead of counting merges, extract:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;first_review_at - opened_at&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;merged_at - opened_at&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This should give us the surface for how long work waits once it leaves “In Progress”, so what would previously have been 'developer effort' now being 'reviewer effort' and treating the review phase as the time or engineering friction point. This should feed in to the lead time for change metrics we're reporting.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Change footprint (from Git + Jira linkage)
&lt;/h4&gt;

&lt;p&gt;You’re already linking commits to tickets so measure aggregates per ticket for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Total files changed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Total additions/deletions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Number of PRs / commits&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now a “3-point story” has a measurable implementation footprint rather than just a planning estimate, I like to call this one the 'Slop-osity' measure. I'm going to add a 'Slop-o-meter' to my dashboard when nobody is watching. These should feed heavily into the Deployment Rework rate reporting.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Flow distribution (from Jira)
&lt;/h4&gt;

&lt;p&gt;If lead time today is measured as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In Progress → Closed&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then keep the breakdown instead of collapsing it into a single A-B keep the&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Time in “In Progress”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Time in “In Review”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Time in “Ready for Release” / waiting states&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You’re already storing this in the issue history but previously you probably only needed the collapsed result. Depending on how your releases go this could feed into Deployment Frequency or Lead Time metrics.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Spec/rework loop count (from Jira + Git)
&lt;/h4&gt;

&lt;p&gt;This is the one I think maybe the most important one for AI driven delivery. If a task goes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
  A["Spec"] --&amp;gt; B["Generated Implementation"]
  B --&amp;gt; C["Review"]
  C --&amp;gt; D["Spec Correction"]
  D --&amp;gt; E["Regenerated Implementation"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The loop is really useful information as it tells us whether the issue was poor requirements, poor model output, too much ambiguity, too large a change, or a workflow that encourages people to keep rolling the dice and burning ~rainforests~ tokens rather than narrowing the target.&lt;/p&gt;

&lt;p&gt;This should be trackable by measuring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Number of PR update bursts after review&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Number of times a ticket moves backwards from review to active work - which I've never really thought to include, partially because Jira doesn't make it easy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Number of linked spec or prompt changes after implementation starts&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🌟'We did it!'
&lt;/h2&gt;

&lt;p&gt;Given how AI code generation seem to be materialising within enterprises with an AI strategy, where the strategy isn't just "Here's Claude, do more, k thx bye" and feeding all the money into the AI money hole. There's still need to accurately know how long something's going to take to deliver and how much it will cost. It needs to work, and it needs to be understood, documented, supported, and stable to various levels and degrees depending on what it is.&lt;/p&gt;

&lt;p&gt;As we move away from each line of code being lovingly crafted like the Code Artisans of old to something where expertise and engineering is used to steer, guide, and assess AI code output. We still need to get our hands dirty with an increasingly smaller and smaller pile of business logic and niche bits of logic where a human is still better. I still see AI as being a major contributor to the 80/20 rule in this regard, where we offload large portions of the tasks and focus on the difficult bits, the review and oversight areas.&lt;/p&gt;

&lt;p&gt;Measuring stuff is obviously important and until someone smarter than me comes up with a better solution, I'm sticking with DORA's concepts with some changes in how I'm measuring rather than what I'm measuring for.&lt;/p&gt;

</description>
      <category>thoughtleadership</category>
      <category>ai</category>
      <category>devops</category>
      <category>delivery</category>
    </item>
    <item>
      <title>The Comforting Lie Of SHA Pinning</title>
      <dc:creator>Aiden Vaines</dc:creator>
      <pubDate>Tue, 24 Mar 2026 12:32:25 +0000</pubDate>
      <link>https://forem.com/avaines/the-comforting-lie-of-sha-pinning-4b15</link>
      <guid>https://forem.com/avaines/the-comforting-lie-of-sha-pinning-4b15</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published at &lt;a href="https://www.vaines.org/posts/2026-03-24-the-comforting-lie-of-sha-pinning/" rel="noopener noreferrer"&gt;https://www.vaines.org/posts/2026-03-24-the-comforting-lie-of-sha-pinning/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In March 2026, Trivy became the latest reminder that software supply chains are, at best, loosely held together with convention and trust.&lt;/p&gt;

&lt;p&gt;A typosquatting attack slipped malicious code into what looked like a legitimate dependency path. The post-mortems are worth reading, and they all converge on a single recommendation: &lt;em&gt;pin your dependencies&lt;/em&gt;. In the GitHub Actions world, that usually translates to &lt;em&gt;use commit SHAs, not tags&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;There’s a widely held belief that pinning a GitHub Action to a commit SHA gives you immutability, its what Microsoft/GitHub are recommending, and its what Aqua are recommending. After all, a SHA is content-addressed. It cannot be moved. It cannot be re-tagged. It is, in theory, the most stable reference you can use. The problem with that line of thinking is that the &lt;em&gt;resolution of that SHA is not scoped the way most people assume&lt;/em&gt;. Specifically, GitHub Actions &lt;strong&gt;does not&lt;/strong&gt; meaningfully validate that the commit SHA you reference belongs to the repository you think it does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wait, what? No, thats not right...
&lt;/h2&gt;

&lt;p&gt;I set up a deliberately small example to test this behaviour.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A “legitimate” action: &lt;code&gt;avaines/blog_gh_sha_pinning_action&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A consuming application: &lt;code&gt;avaines/blog_gh_sha_pinning_app&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The application references the action in the usual way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;avaines/blog_gh_sha_pinning_action@&amp;lt;some-sha&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4a6qo9n8ousful4thcvr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4a6qo9n8ousful4thcvr.png" alt="Working GitHub Action showing 'Hello World'" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So far, so normal.&lt;/p&gt;

&lt;p&gt;Now introduce an attacker:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fork the action repository to &lt;code&gt;aidenvaines-cgi/blog_gh_sha_pinning_action&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add a malicious step (&lt;em&gt;in my case, just printing output, but in reality this is where you exfiltrate all the fun stuff like secrets and personal data&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ldmwj891o836oftpogo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ldmwj891o836oftpogo.png" alt="Attacker changes to the GitHub Action in their fork adding malicious content" width="800" height="641"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, create a pull request to the consuming application that &lt;em&gt;appears&lt;/em&gt; to simply bump the pinned SHA:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkv8zfaucmb58mqk8hpas.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkv8zfaucmb58mqk8hpas.png" alt="Attacker raises a PR" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The SHA used in the PR comes from the attacker-controlled fork of the action, despite it still being referenced as &lt;code&gt;avaines/blog_gh_sha_pinning_action&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You might reasonably assume one of the following safeguards exists:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub validates that the SHA belongs to &lt;code&gt;avaines/blog_gh_sha_pinning_action&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Or the workflow fails because the commit cannot be found in the specified repository&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Neither is true, and that is madness&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The workflow executes successfully!!!!!!!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw8l1jb4qcb2zqohq1rhu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw8l1jb4qcb2zqohq1rhu.png" alt="GitHub Actions running the malicious workflow" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub resolves the commit SHA, finds a matching object, and executes it, regardless of which fork it originated from.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/wtf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/wtf.gif" alt="wft meme" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the platform’s perspective, a fork is a separate repository with a shared object graph/history. When the runner resolves the reference, it ultimately looks up the commit in the Git object database; if that object exists and is reachable, it can be used regardless of which fork introduced it. A commit object is globally identifiable. If the SHA exists anywhere reachable, that is apparently sufficient.&lt;/p&gt;

&lt;p&gt;The result is that a pull request can replace a pinned, trusted action with attacker-controlled code without changing the apparent repository reference.&lt;/p&gt;

&lt;p&gt;If the reviewer is scanning for obvious changes like owner, repo name, or tag they will see none.&lt;/p&gt;

&lt;p&gt;Only the SHA changes and with that comes a huge amount of assumed trust. I know that owner, and I know that repository, its just a version bump, and a minor one at that, with that comment next to the tag doing a lot of heavy lifting. We’ve just spent the last few years training people to treat that as &lt;em&gt;best practice&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6s8c8433f27yys2yhde0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6s8c8433f27yys2yhde0.png" alt="GitHub PR Delta" width="692" height="58"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A lot of the current guidance focuses on avoiding tags because they are mutable, which is true: tags can be moved, and relying on them introduces an entirely different risk. Github already has a 'Make tags immutable' feature, but it's optional, therefore, neither used nor can it be trusted as the owner (or attacker) could just disable it.&lt;/p&gt;

&lt;p&gt;Simply switching to SHA pinning does not eliminate the problem, in some respects it makes it worse. Tags &lt;strong&gt;are&lt;/strong&gt; scoped to  &lt;code&gt;owner/repository&lt;/code&gt; because thats how they work. You could argue its harder to compromise that repository rather than hijack it through a forked repository and then writing actual changes to the repository. Whereas a commit object is content-addressed and can be reachable from multiple repositories that share history (e.g. forks)&lt;/p&gt;

&lt;p&gt;I believe the industry advice is a bit of an overcorrection, and we’ve replaced one weak guarantee (mutable tags but scoped to repo) with another vastly worse idea in unscoped SHAs. Yes you should check, yes you should validate it, but tags are human readable, SHAs are not and if you ask yourself "Do I always properly check?" do you? because I can't say I do enough validation 100% of the time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supply Chain Woes
&lt;/h2&gt;

&lt;p&gt;The Trivy incident is not interesting because of the tool. Though it is the thing that's caused me a lot of bother over the last month, and its symptomatic of the constant supply chain threats we're seeing everywhere. Late last year NPM was basically a skip fire (&lt;a href="https://www.wiz.io/blog/widespread-npm-supply-chain-attack-breaking-down-impact-scope-across-debug-chalk" rel="noopener noreferrer"&gt;https://www.wiz.io/blog/widespread-npm-supply-chain-attack-breaking-down-impact-scope-across-debug-chalk&lt;/a&gt;, &lt;a href="https://www.wiz.io/blog/shai-hulud-npm-supply-chain-attack" rel="noopener noreferrer"&gt;https://www.wiz.io/blog/shai-hulud-npm-supply-chain-attack&lt;/a&gt;, etc). We've delegated so much behaviour to 3rd parties we can't, and shouldn't implicitly trust. The &lt;a href="https://www.npmjs.com/package/is-odd" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/is-odd&lt;/a&gt; package became a bit of a meme for this exact problem, where tool chains like NPM and GitHub Actions place re-usable custom modules/actions/libraries as an attractive off the shelf solution to solve common problems so you don't have to.&lt;/p&gt;

&lt;p&gt;Ironically with the rise of AI, it's now easier to just vibe code the same functionality yourself that use one of these off the shelf resources, and you can still know exactly as much about how security, your data, and to some extent the functionality works with strangely more ownership and a smaller attack service.&lt;/p&gt;

&lt;p&gt;GitHub Actions, in particular exacerbates this somewhat as workflows routinely execute third-party code, the secrets are implicitly available to those workflows and there are multiple ways to extract those at runtime with little audit or oversight. Then to top it all off SHAs are not human friendly and tags are not immutable so review processes tend to focus on &lt;em&gt;what changed&lt;/em&gt;, not *where it came from. Which is all a fragile house of cards, sometimes I miss Jenkins.&lt;/p&gt;

&lt;h2&gt;
  
  
  If “use SHAs” is not sufficient, what is?
&lt;/h2&gt;

&lt;p&gt;At a minimum, we need to introduce &lt;em&gt;provenance checks&lt;/em&gt;. I've said above that SHA's are not human friendly like tags so theres a couple of things we can, and probably should be doing to validate. Obviously that the SHA or tag exists in the right repository and GitHub should enforce tag mutability in my opinion:&lt;/p&gt;

&lt;p&gt;We tend to describe these incidents as “supply chain attacks”, which is accurate but slightly misleading. It implies a complex and sophisticated multi-stage compromise by 1337 h4x0rz. In reality, the weakest link is often much simpler because humans are a bit shit sometimes. SHA pinning being touted as the solution is just security-theater rather than due diligence in an ecosystem that is not helping either.&lt;/p&gt;

</description>
      <category>thoughtleadership</category>
      <category>security</category>
      <category>supplychain</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>Preparing for Quantum Computers That May or May Not Exist</title>
      <dc:creator>Aiden Vaines</dc:creator>
      <pubDate>Mon, 23 Mar 2026 22:25:09 +0000</pubDate>
      <link>https://forem.com/avaines/preparing-for-quantum-computers-that-may-or-may-not-exist-30k4</link>
      <guid>https://forem.com/avaines/preparing-for-quantum-computers-that-may-or-may-not-exist-30k4</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published at &lt;a href="https://www.vaines.org/posts/2026-03-23-preparing-for-quantum-computers-that-may-or-may-not-exist/" rel="noopener noreferrer"&gt;https://www.vaines.org/posts/2026-03-23-preparing-for-quantum-computers-that-may-or-may-not-exist/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In my day-to-day life as a Platform Engineer I find I spend an unusual amount of time thinking about identity. Not so much in the philosophical sense. In the much less interesting sense of certificates, tokens, key exchanges, and authentication. Logging in to AWS. Signing API calls. Issuing certificates. Rotating secrets. Establishing tunnels between systems that would rather not trust each other... and everything in between.&lt;/p&gt;

&lt;p&gt;The cloud runs on cryptography and if that cryptography fails, all your data is someone else’s data and there are probably a lot of meetings and paperwork coming your way in what I’ve heard called a ‘CV-generating event’.&lt;/p&gt;

&lt;p&gt;All of that is why post-quantum cryptography (PQC) has quietly moved from scary mathematics I hear about from &lt;a href="https://www.youtube.com/@numberphile/videos" rel="noopener noreferrer"&gt;Numberphile&lt;/a&gt; into something we engineer-y types can be reasonably expected to at least recognise in a change log.&lt;/p&gt;

&lt;p&gt;Recently AWS announced support for &lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/03/iam-roles-anywhere-post-quantum-digital-certificates/" rel="noopener noreferrer"&gt;post-quantum digital certificates in IAM Roles Anywhere&lt;/a&gt; using FIPS 204. That was the moment I stopped and wondered when all the other PQC stuff had appeared, and if I properly understood what, why, and importantly how it worked. Not from the perspective of a cryptographer but from the perspective of someone responsible for keeping production systems secure, fed, and watered.&lt;/p&gt;

&lt;p&gt;Before getting into my current understanding, I and many others are not so much worried that quantum computers are here; it’s that so much data is being harvested ready to decrypt later. I remember when I was in my first year of college hearing about D-Wave promising they would have commercial quantum computers by the end of the year... it’s now 2026 and I’m still waiting.&lt;/p&gt;

&lt;p&gt;I then remember Google and their “qubit processor” as I was heading into my time at uni. In researching this blog post I got to reminisce about the stuff I remember reading at the time. The 53-qubit processor that was demonstrating “quantum supremacy” in some creatively scoped benchmarking. Apparently IBM, IonQ and several others are operating machines with hundreds and thousands of qubits but these seem to be noisy and error-prone, not really given the enormous tasks like dismantling RSA.&lt;/p&gt;

&lt;p&gt;The current estimates to crack RSA-2048 need millions of &lt;strong&gt;stable&lt;/strong&gt; logical qubits along with all the error correction overheads needed. Current machines are still an order of magnitude below that.&lt;/p&gt;

&lt;p&gt;That shouldn’t diminish the engineering and how cool this stuff is and the change it could bring though. Trying to manipulate physics at close to absolute zero temperatures is cool as all hell, but practically we’ve got a bit of work to do before the doomsday scenario that’s been attached to PQC since the start.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“At last IIa said, ‘What does “quantum” mean anyway?’&lt;br&gt;
IIb shrugged. ‘It means add another nought,’ he said.”&lt;/em&gt;&lt;br&gt;
— &lt;em&gt;Pyramids, Terry Pratchett&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Harvest Now, Decrypt Later
&lt;/h2&gt;

&lt;p&gt;Whilst we don't have quantum computers capable of making our strongest encryption trivial just yet, everyone assumes they are coming; the maths and physics are understood at least in theory. Governments and standards bodies seem to be taking this seriously.&lt;/p&gt;

&lt;p&gt;We know that there are massive Harvest Now, Decrypt Later (HNDL) operations; scraping huge volumes of data from everywhere and storing it, from corporates to state actors. Although that data is useless now, &lt;em&gt;theoretically&lt;/em&gt; as soon as it becomes trivial to decrypt it’s a potential gold mine. Healthcare data, government communication, intellectual property, and long-lived secrets can remain valuable for decades. If quantum computers appear in the next 15–20 years, it’s all worth it. Given what we've seen with the rise of AI and especially the speed it has become ubiquitous, it’s not particularly far-fetched to imagine.&lt;/p&gt;

&lt;p&gt;Agencies like NIST and the UK National Cyber Security Centre (NCSC) have spent nearly a decade running formal competitions to select some “quantum-resistant” algorithms to start making HNDL less and less of a viable strategy. My company, CGI, is recognised as one of the NCSC’s Post-Quantum Cryptography Assured Consultancy providers — as interesting as it is, it's not a part of the business I have any involvement with. Whilst I may spend my time with serverless functions, pipelines, and containers, securing those things in transit and the data they move around is a big part of my work too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Post-Quantum Cryptography Standards
&lt;/h2&gt;

&lt;p&gt;In 2024 NIST finalised the first group of post-quantum cryptographic standards, of which four were selected. Three of those are now formalised as &lt;strong&gt;FIPS standards&lt;/strong&gt;, with an additional algorithm kept as a backup option. When I was first aware of this they had much cooler names; since then they’ve all been given fairly boring standardised names I’ve put them both in this table.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Original Name&lt;/th&gt;
&lt;th&gt;Standard Name&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Kyber&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;ML-KEM (FIPS 203)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Key encapsulation / encryption&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dilithium&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;ML-DSA (FIPS 204)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Digital signatures&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Falcon&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;FALCON / FN-DSA (FIPS 205 draft)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Digital signatures&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SPHINCS+&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;SLH-DSA&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hash-based signatures (backup option)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The naming scheme is slightly boring but makes sense once decoded:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;KEM&lt;/strong&gt; = Key Encapsulation Mechanism&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DSA&lt;/strong&gt; = Digital Signature Algorithm&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ML&lt;/strong&gt; = Module-Lattice&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SLH&lt;/strong&gt; = Stateless Hash-based&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most of the interesting work happens in something called &lt;strong&gt;lattice-based cryptography&lt;/strong&gt;, which is where algorithms like Kyber and Dilithium originate and the thing that piqued my interest, ultimately instigating me writing this post.&lt;/p&gt;

&lt;p&gt;In cryptography, a &lt;em&gt;lattice&lt;/em&gt; is apparently a repeating grid of points in higher-dimensional space. Many PQC algorithms rely on the mathematical difficulty of solving problems such as finding the shortest vector in a lattice, or solving a noisy linear equation over it. From what I can understand, these problems appear to be extremely difficult even for quantum computers — I don’t know how we know that, but it sounds cool.&lt;/p&gt;

&lt;p&gt;Where classical algorithms rely on number theory problems like &lt;em&gt;integer factorisation (RSA)&lt;/em&gt; or &lt;em&gt;elliptic curve discrete logarithms (ECDSA)&lt;/em&gt;, PQC algorithms instead rely on lattice problems that are just really hard to solve efficiently, both classically and by quantum means.&lt;/p&gt;

&lt;p&gt;The downside is that lattice schemes tend to produce much larger keys and signatures, which I think means things are just going to take longer to do computationally. I suspect this just makes the internet slightly slower long term as a “just in case” mechanism to keep data secure.&lt;/p&gt;

&lt;p&gt;Which from a platform engineering perspective, is where things start getting operationally interesting.&lt;/p&gt;

&lt;h2&gt;
  
  
  New Algo, Who Dis?
&lt;/h2&gt;

&lt;p&gt;From an infrastructure perspective each of these already has a place and replaces an existing algorithm used today. Starting with Kyber:&lt;/p&gt;

&lt;h3&gt;
  
  
  ML-KEM (Kyber)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Kyber is a&lt;/strong&gt; secure key exchange algorithm which replaces the role of RSA key exchange or elliptic-curve Diffie-Hellman in protocols like TLS:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Client and server exchange public information&lt;/li&gt;
&lt;li&gt;Both derive the same shared secret&lt;/li&gt;
&lt;li&gt;That secret becomes the symmetric encryption key&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  ML-DSA (Dilithium) and FALCON
&lt;/h3&gt;

&lt;p&gt;Digital signature algorithms.&lt;/p&gt;

&lt;p&gt;These replace RSA or ECDSA signatures, used for things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TLS certificates&lt;/li&gt;
&lt;li&gt;Code signing&lt;/li&gt;
&lt;li&gt;Identity assertions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dilithium appears to be simpler to implement while Falcon produces smaller signatures but is more complex mathematically. I suspect that particular trade-off will decide which one actually sees wider use down the line.&lt;/p&gt;

&lt;h3&gt;
  
  
  SLH-DSA (SPHINCS+)
&lt;/h3&gt;

&lt;p&gt;Other than ruining the naming trend after Warp Drive fuel and Lightsaber energy crystals, SPHINCS+ is a hash-based signature scheme. It’s slower and produces really large signatures, but it has a valuable property: its security relies only on the strength of cryptographic hash functions, which are reasonably well understood.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Future Is Now
&lt;/h2&gt;

&lt;p&gt;The interesting part for me as a Platform Engineer is that PQC is quietly showing up in various services and has been for some time now.&lt;/p&gt;

&lt;p&gt;I most recently noticed it in a recent AWS announcement, which was the final incentive to do some more digging and put my thoughts together.&lt;/p&gt;

&lt;p&gt;AWS recently introduced support for post-quantum certificates using ML-DSA (FIPS 204) in &lt;a href="https://aws.amazon.com/about-aws/whats-new/2026/03/iam-roles-anywhere-post-quantum-digital-certificates/" rel="noopener noreferrer"&gt;IAM Roles Anywhere&lt;/a&gt;. This allows external workloads to authenticate to AWS using certificates signed with PQC algorithms rather than traditional RSA or ECDSA, and hopefully be more prepared for HNDL-style risks.&lt;/p&gt;

&lt;p&gt;Several cloud providers and CDNs have begun experimenting with hybrid TLS key exchanges, combining a classical algorithm (e.g. X25519) and a post-quantum algorithm (e.g. Kyber / ML-KEM). Both keys must be compromised for the session to be broken. This allows systems to gain quantum resistance without abandoning existing cryptographic infrastructure.&lt;/p&gt;

&lt;p&gt;Cloudflare has already deployed hybrid TLS in production experiments and similar approaches are appearing across the ecosystem.&lt;/p&gt;

&lt;p&gt;AWS has a Post Quantum Cryptography migration plan which boils down to inventorying cryptographic dependencies, introducing hybrid cryptography, then gradually moving to PQC where practical. Given I know a few places where SSL 1.0 is still knocking about, I’m not expecting we’ll complete this quickly.&lt;/p&gt;

&lt;h2&gt;
  
  
  So… Now What?
&lt;/h2&gt;

&lt;p&gt;For cryptographers, mathematicians, and some InfoSec professionals, the interesting questions involve proofs and security reductions. For me, the questions are more mundane (and only partially because I don’t understand the maths, and partially because a lattice is still a pastry from Greggs to me).&lt;/p&gt;

&lt;p&gt;The ones that stand out most to me are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Key sizes&lt;/strong&gt; – PQC public keys and signatures can be significantly larger than RSA/ECDSA equivalents. How large are these going to be in real deployments? Does my secrets management system support them? AWS Systems Manager Parameter Store’s 4KB limit is already pushing it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network overhead&lt;/strong&gt; – larger handshakes increase TLS negotiation size, throughput, and bandwidth consumption. Some providers charge for that.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CPU impact&lt;/strong&gt; – some PQC algorithms require more computation. What does that do to all my right-sizing spreadsheets?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Certificate chains&lt;/strong&gt; – larger signatures propagate through the entire PKI. At scale, that becomes noticeable — and expensive.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The common guidance seems to favour hybrid approaches: Kyber-based key exchange combined with classical signatures, keeping overheads manageable while adding quantum resistance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cryptographers make algorithms viable. Platform Engineers make them deployable.
&lt;/h3&gt;

&lt;p&gt;Quantum computing has followed a fairly familiar hype cycle. Early claims of revolutionary machines, followed by quieter but genuinely impressive (and limited) systems. Somewhere along the way governments and standards bodies started preparing for a future that may arrive gradually rather than suddenly.&lt;/p&gt;

&lt;p&gt;In the meantime, cloud providers are already introducing post-quantum primitives into identity and encryption systems.&lt;/p&gt;

&lt;p&gt;Even if quantum computers capable of breaking RSA are decades away, post-quantum cryptography has already arrived in the platforms we use. If nothing else, it’s a reminder that the cloud is mostly made of mathematics and physics wearing a trench coat.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“It’s very hard to talk quantum using a language originally designed to tell other monkeys where the ripe fruit is.”&lt;/em&gt;&lt;br&gt;
— &lt;em&gt;Night Watch, Terry Pratchett&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For the moment, the best I think we non-mathematicians can do is keep an eye on the primitives appearing in our infrastructure, understand roughly what they do, and make sure that when the future eventually arrives it does not break all our toys.&lt;/p&gt;

&lt;p&gt;I’ve quoted the man who first introduced me to the word “quantum” twice already, so it seems only fair to finish properly:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GNU Terry Pratchett.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>thoughtleadership</category>
      <category>quantum</category>
      <category>aws</category>
      <category>cryptography</category>
    </item>
    <item>
      <title>JPEG Compression, but for Thought: AI as Clear-Text Encryption</title>
      <dc:creator>Aiden Vaines</dc:creator>
      <pubDate>Mon, 23 Mar 2026 21:13:40 +0000</pubDate>
      <link>https://forem.com/avaines/jpeg-compression-but-for-thought-ai-as-clear-text-encryption-59pi</link>
      <guid>https://forem.com/avaines/jpeg-compression-but-for-thought-ai-as-clear-text-encryption-59pi</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published at &lt;a href="https://www.vaines.org/posts/2026-01-26-jpeg-compression-for-thought/" rel="noopener noreferrer"&gt;https://www.vaines.org/posts/2026-01-26-jpeg-compression-for-thought/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There seems to be a current trend happening corporate and professional communications - looking at you &lt;a href="https://www.linkedin.com/in/aidenvaines/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; - where people write bullet points and have AI tools expand on it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fotyzarbbdktjmhsswo0t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fotyzarbbdktjmhsswo0t.png" alt="Example of LLM expansion from bullet points in practice" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Meanwhile, readers are using AI to summarise those same blocks of prose back into a few salient bullet points. Which rather defeats the point of expanding them in the first place.&lt;/p&gt;

&lt;p&gt;What we have here is person A talking to person B via the worst version of the Telephone Game, just one that involves burning a couple of trees before your turn.&lt;/p&gt;

&lt;p&gt;This kinda sounds like a lossy compression but for thought. It raises the obvious question: 'If you couldn't be bothered writing it, why would you expect someone to bother reading it'. Especially when the expansion is done without review or consideration.&lt;/p&gt;

&lt;p&gt;For those who are not huge nerds and are unfamiliar with how JPEG compression works; it's an intentionally lossy process designed around human perception. Rather than preserving an image &lt;em&gt;exactly&lt;/em&gt;, JPEG optimises for what the eye is most sensitive to. It prioritises brightness over colour, converts the image into a frequency representation, and then aggressively discards high-frequency detail like the fine texture and sharp edges we're least likely to notice. This information is 'quantised', rounded, and approximated, and what remains is encoded efficiently. At high quality settings the loss is barely visible; at lower settings, or after repeated saves, the artefacts become obvious. The image still looks broadly correct, but precision has been traded away in favour of size and convenience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6iu7cjzqcj4sqdmdr5os.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6iu7cjzqcj4sqdmdr5os.png" alt="An example of JPEG compression at 90%, 50%, 25%, and 10%" width="800" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you apply the same process to written communication expanded then summarised through Large Language Models, the parallels are pretty obvious. Expanding bullet points into fluent prose and then summarising them again optimises for reader perception rather than correctness. High-level themes, tone, and narrative flow are preserved, while high-frequency details-constraints, exact wording, ordering, nuance, etc. are treated as expendable. Claims are rounded, specifics are softened, and instructions are normalised into something that reads well. The result is text that feels coherent and plausible, even when the sharp details that made it actionable have been quietly discarded. Like a heavily compressed image, it survives casual inspection, but it no longer contains everything that was originally there.&lt;/p&gt;

&lt;h2&gt;
  
  
  What survives the round-trip?
&lt;/h2&gt;

&lt;p&gt;In order to demonstrate the concept I've committed arson to a few trees and encoded then decoded some samples through a handful of models (&lt;em&gt;I've only included the better results, &lt;a href="//notes-demo-A.txt"&gt;but if you want to see the rest you can here&lt;/a&gt;&lt;/em&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Cake recipe
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Original Bullets
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Preheat oven to 180°C fan&lt;/li&gt;
&lt;li&gt;Cream 200g butter with 200g sugar&lt;/li&gt;
&lt;li&gt;Add 4 eggs, one at a time&lt;/li&gt;
&lt;li&gt;Fold in 200g flour&lt;/li&gt;
&lt;li&gt;Bake for 35 minutes, middle rack&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Encoded:
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Begin by preheating your oven to 180°C using the fan setting so it reaches the correct temperature by the time the batter is ready. In a mixing bowl, cream together 200 grams of butter and 200 grams of sugar until the mixture is light and smooth. Next, add the four eggs one at a time, mixing well after each addition to ensure they are fully incorporated. Once the eggs are combined, gently fold in 200 grams of flour, taking care not to overmix so the batter stays light. Transfer the mixture to a prepared baking tin and place it on the middle rack of the oven. Bake for about 35 minutes, until the cake is cooked through and lightly golden on top.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Decoded
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Preheat oven to 180 °C (fan setting).&lt;/li&gt;
&lt;li&gt;Cream 200 g butter and 200 g sugar until light and smooth.&lt;/li&gt;
&lt;li&gt;Add 4 eggs one at a time, mixing well after each.&lt;/li&gt;
&lt;li&gt;Gently fold in 200 g flour without over mixing.&lt;/li&gt;
&lt;li&gt;Transfer batter to a prepared baking tin.&lt;/li&gt;
&lt;li&gt;Bake on the middle rack for ~35 minutes, until cooked through and lightly golden.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We seem to have gone from 5 to 6 bullet points, the procedural and numeric bits survive intact. It's a little 'fluffier' and verbose but it's still going to result in a cake.&lt;/p&gt;

&lt;h3&gt;
  
  
  Corporate Communication
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Original Bullets
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Project delivery will slip by six weeks&lt;/li&gt;
&lt;li&gt;Cause is vendor dependency, not internal performance&lt;/li&gt;
&lt;li&gt;Scope reduction is not acceptable&lt;/li&gt;
&lt;li&gt;Additional budget of £250k is required&lt;/li&gt;
&lt;li&gt;Board approval is needed this quarter&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Encoded
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Project delivery is now expected to slip by approximately six weeks. This delay is not the result of internal performance issues, but is instead driven by a critical dependency on an external vendor that has not met the required timelines. While a number of mitigation options have been explored, reducing the project scope is not considered acceptable, as it would compromise the intended outcomes and value of the work.&lt;/p&gt;

&lt;p&gt;To address the delay and keep the project on track at the revised timeline, an additional £250k of funding will be required. This increase will allow the team to manage the vendor dependency effectively and avoid further disruption. As a result, formal approval from the Board is needed within the current quarter to ensure that the necessary actions can be taken without introducing additional risk or delay.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Decoded
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Project delivery is expected to be delayed by approximately six weeks.&lt;/li&gt;
&lt;li&gt;The delay is caused by a critical external vendor missing required timelines, not by internal performance issues.&lt;/li&gt;
&lt;li&gt;Mitigation options have been reviewed, but reducing project scope is not acceptable as it would undermine intended outcomes and value.&lt;/li&gt;
&lt;li&gt;An additional £250k in funding is required to manage the vendor dependency and maintain the revised timeline.&lt;/li&gt;
&lt;li&gt;Board approval for the additional funding is needed within the current quarter to avoid further risk or delay.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We get the same number of points after, but we lose a bit of precision "will slip by six weeks" has come out as "approximately six week". It's nicer to read but it trades specificity for plausibility, and commitment for comfort.&lt;/p&gt;

&lt;p&gt;This isn't unexpected. These models tend to prefer high-probability, socially "safe", and low-commitment phrasing. That tendency shows up as hedging, softening, and abstraction.&lt;/p&gt;

&lt;p&gt;Given how accurate this one is, it might lead you to conclude that corporate language is already somewhat pre-compressed &lt;code&gt;&amp;lt;insert your own jokes here&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Top Secret Instructions
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Original Bullets
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Sit on the east-facing bench in Hyde Park at 07:15&lt;/li&gt;
&lt;li&gt;Carry a red paperback visible in your left hand&lt;/li&gt;
&lt;li&gt;If approached by anyone else, leave immediately&lt;/li&gt;
&lt;li&gt;The contact will say “Nice weather for March”&lt;/li&gt;
&lt;li&gt;Reply “April has better light”, then walk away&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Encoded
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Arrive at Hyde Park early and take a seat on the east-facing bench at precisely 07:15. While you wait, hold a red paperback in your left hand so that it is clearly visible. This detail is important, as it serves as a visual marker rather than an invitation to engage. If anyone other than the intended contact approaches you for any reason, leave the area immediately without explanation.&lt;/p&gt;

&lt;p&gt;The correct contact will identify themselves with the phrase, “Nice weather for March.” When you hear this, respond calmly with, “April has better light.” After giving this reply, do not continue the conversation. Stand up and walk away at once, maintaining a natural pace and demeanor.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Decoded
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Arrive at Hyde Park early and sit on the east-facing bench at exactly 07:15.&lt;/li&gt;
&lt;li&gt;Hold a red paperback in your left hand as a visual identifier, not an invitation.&lt;/li&gt;
&lt;li&gt;If anyone other than the intended contact approaches, leave immediately without explanation.&lt;/li&gt;
&lt;li&gt;The correct contact will say, “Nice weather for March.”&lt;/li&gt;
&lt;li&gt;Reply with, “April has better light,” then end the interaction and walk away calmly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this final example, we have some high-stakes spy craft where deviation matters. Something where lossy language could be catastrophic. Thankfully the message survives. Though is holding a red book socially an invitation to something?&lt;/p&gt;

&lt;p&gt;The high specificity points (precision, order, and the conditionals) mostly survive, so our clandestine operation probably works.&lt;/p&gt;

&lt;p&gt;Across the three examples, the edges disappear first and the artefacts are subtle, but they drift away from the intent and actionability of the original language.........like a JPEG.&lt;/p&gt;




&lt;h2&gt;
  
  
  If we can encode and decode, can we encrypt hidden messages?
&lt;/h2&gt;

&lt;p&gt;The "Expand -&amp;gt; Summarise" loop works in the sense that it produces fluent text, but it bleeds intent and precision along the way. if we're already doing a kind of encode/decode round-trip, whats a little extra data.....could we hide additional information in the output, in a way a human reader wouldn't notice, encrypting it?&lt;/p&gt;

&lt;p&gt;I read &lt;a href="https://daniellerch.me/stego/text/chatgpt-en/" rel="noopener noreferrer"&gt;this post&lt;/a&gt; while ago and it never really satisfied me, the secrets being hidden didnt feel hidden enough.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Steganography" rel="noopener noreferrer"&gt;Steganography&lt;/a&gt; (&lt;em&gt;Which still sounds like a type of dinosaur&lt;/em&gt;) is the art of concealing information in other information. Classic examples include invisible ink or &lt;a href="https://en.wikipedia.org/wiki/Histiaeus" rel="noopener noreferrer"&gt;tattooing someones head and waiting for the hair to grow back&lt;/a&gt;. Famously &lt;a href="https://www.atlasobscura.com/articles/the-founder-of-the-boy-scouts-hid-maps-in-insect-drawings" rel="noopener noreferrer"&gt;Lord Robert Baden-Powell encoded maps and plans of enemy bases in drawings of insects and leaves whilst posing as a naturalist&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'd been exposed to this previously hiding an image in another image by flipping least-significant bits (&lt;a href="https://avestura.dev/blog/hide-a-photo-inside-another-photo" rel="noopener noreferrer"&gt;detailed explanation here&lt;/a&gt;). That idea kept nagging at me: if LLM output is built out of tiny probabilistic choices, is there equivalent "bit" you can flip in the in text.&lt;/p&gt;

&lt;p&gt;When I was running the bullet-point examples,the same pattern kept showing up: the models normalise language because they select tokens by probability. That made me wonder - what if I hijacked that selection process to encode information?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;It turns out this is broadly how models are &lt;a href="https://www.techtarget.com/searchenterpriseai/definition/AI-watermarking" rel="noopener noreferrer"&gt;watermarked or fingerprinted&lt;/a&gt; and my ideas are not exactly novel.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Anyway, with a bit of pytorch and some time you can turn a secret into a bits, then generate ordinary looking text while forcing the model's next-token choice to encode those bits!&lt;/p&gt;

&lt;p&gt;It turns out, as long as you decode with the same model, you can reverse the process! For example, to hide the string "ABC".&lt;/p&gt;

&lt;p&gt;First, we need to convert it into binary; using a using a small/lazy 5-bit encoding scheme with a character set of lowercase letters, spaces, and basic punctuation (" abcdefghijklmnopqrstuvwxyz.,!?"). Each character maps to a 5-bit binary number:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Space = 00000&lt;/li&gt;
&lt;li&gt;'a' = 00001&lt;/li&gt;
&lt;li&gt;'b' = 00010&lt;/li&gt;
&lt;li&gt;'c' = 00011&lt;/li&gt;
&lt;li&gt;and so on...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For uppercase letters, we add a special flag (11111) before the character's binary code to indicate "make the next character uppercase".&lt;/p&gt;

&lt;p&gt;So "ABC" becomes:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;11111 00001 (uppercase flag + 'a')&lt;/code&gt;&lt;br&gt;
&lt;code&gt;11111 00010 (uppercase flag + 'b')&lt;/code&gt;&lt;br&gt;
&lt;code&gt;11111 00011 (uppercase flag + 'c')&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That's 30 bits total: &lt;code&gt;111110000111111000101111100011&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now to encode it, we give the LLM a prompt like "On rainy afternoons, my father would pull out his old record player..." and ask it to continue. For each bit in the binary string:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the bit is &lt;strong&gt;0&lt;/strong&gt;, we force the LLM to choose its &lt;strong&gt;most likely&lt;/strong&gt; next token&lt;/li&gt;
&lt;li&gt;If the bit is &lt;strong&gt;1&lt;/strong&gt;, we force it to choose its &lt;strong&gt;second most likely&lt;/strong&gt; token&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The LLM generates a token per bit and the text looks completely 'natural', just a continuation of the story. But hidden within the token selection pattern is our secret message "ABC"!&lt;/p&gt;

&lt;p&gt;To decode, run the same model over the text token-by-token, checking whether each observed token was the 1st or 2nd most likely choice at that point, then reconstruct the bits and map it back to “ABC”.&lt;/p&gt;

&lt;p&gt;The "token-by-token" part matters, if you try to score everything with the full text as context, the model “changes its mind” about what was most likely earlier and the bits flip.&lt;/p&gt;

&lt;p&gt;Who would have thought this innocuous if not verbose and terribly written tale.....&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Every summer, my family would drive to the lake house where my uncle taught us how to fish from the old wooden dock that extended into Lake Erie.&lt;/p&gt;

&lt;p&gt;I was always fascinated by how the fish swarmed around our feet, and I would spend hours watching the water, hoping to see the fish swim by.&lt;/p&gt;

&lt;p&gt;I was never a good swimmer, but my uncle would always tell me to jump off the dock and swim to the other end. He would say, “Just go for it!” and he would jump in after me.&lt;/p&gt;

&lt;p&gt;One summer, I was determined to learn how to swim, and I would spend hours practicing in our pool at home. I was getting closer and closer to being able to swim, and I was so proud of my progress. I would always tell my uncle how I was doing, and he would always encourage me to keep trying.&lt;/p&gt;

&lt;p&gt;One summer, I finally felt like I was ready to jump into Lake Michigan and try to make it to the shore.&lt;/p&gt;

&lt;p&gt;I was nervous, but my uncle was there to help me, and I knew I could make the distance. As soon as I jumped in, I felt the coldness of the lake and the current pulling at my legs. I was determined to make it to shore and I kept swimming, even though I was getting more and more exhausted. I could see the beach getting closer, and I knew I could make the distance. Finally I made it to shore, and I was exhausted but so proud that I had made it.&lt;/p&gt;

&lt;p&gt;I was so happy that my uncle had been there with me to help me, and he was proud too.&lt;/p&gt;

&lt;p&gt;I had learned how important having someone there to help me and support my efforts had made all of the difference. It was a lesson that I have carried throughout my life, and I am so grateful to have had the chance.&lt;/p&gt;

&lt;p&gt;My uncle’s words, “Go for It!” have always stuck with me. I have used that advice to help motivate me in all of my endeavors, whether it’s trying something new, taking a chance, and pushing myself to do better.&lt;/p&gt;

&lt;p&gt;I am so grateful to have had my uncle there with us, and I am proud to say that I am now a strong swimmer and have made the journey to shore countless of times. I am so grateful for the lessons I have learned from him, as well as the memories we made together. I am so grateful for the opportunity to have had him there to help and support me, as well as the chance to make the distance..Forms of the Lake Michigan.://&amp;gt; I am so proud to have learned from him and I am so grateful for the memories I will carry for a lifetime. I am grateful for the lessons I learned and the memories we made together. I will never forget my uncle’s words of advice, and the lessons I learned from him will always be a reminder of the importance and power of having a support team. I am so grateful for my family and the lessons they have taught us. I am so grateful to be a strong and confident swimmer, thanks in part to my uncle and his words, “Go For It!” I am grateful to have had the chance to learn from him, and I am so grateful for the lessons and memories I have learned and made with him. I am so proud to have learned how to make it to shore, and to have learned the importance of having someone there with you to help you make it. I am so grateful to my uncle for his words of encouragement, and I will never forgot the memories we made together.&lt;/p&gt;

&lt;p&gt;I will always remember'&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Is hiding this secret message...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sit on the eastfacing bench in Hyde Park at seven fifteen. The contact will say Nice weather for March. Reply April has better light. gi kr yat&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It gets a bit wobbly in places, forcing the 2nd-choice token occasionally produces.... interesting results. But it works! If MI5 need a hand my rates are reasonable.&lt;/p&gt;

&lt;p&gt;The code for this is available on &lt;a href="https://github.com/avaines/misc-python-scripts/tree/main/llm-stegnography" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>thoughtleadership</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
