<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Sau Sheong on Medium]]></title>
        <description><![CDATA[Stories by Sau Sheong on Medium]]></description>
        <link>https://medium.com/@sausheong?source=rss-a358058b2410------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*WkI-QZSw5H8mlDK4fppJ_w@2x.jpeg</url>
            <title>Stories by Sau Sheong on Medium</title>
            <link>https://medium.com/@sausheong?source=rss-a358058b2410------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 05 Nov 2026 04:15:11 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@sausheong/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Why Change is Hard]]></title>
            <link>https://medium.com/@sausheong/why-change-is-hard-274436d0a42a?source=rss-a358058b2410------2</link>
            <guid isPermaLink="false">https://medium.com/p/274436d0a42a</guid>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[malcolm-gladwell]]></category>
            <category><![CDATA[change-management]]></category>
            <category><![CDATA[career-change]]></category>
            <dc:creator><![CDATA[Sau Sheong]]></dc:creator>
            <pubDate>Mon, 12 Oct 2026 05:02:04 GMT</pubDate>
            <atom:updated>2026-10-12T05:40:05.705Z</atom:updated>
            <content:encoded><![CDATA[<h4><em>Change is hard when it asks us to rethink who we are</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*b4CoQxYe1oF_c4e2QFHAOg.png" /></figure><p>Last week in Seattle, I attended Malcolm Gladwell’s session at Slalom’s R4 2026 conference. Gladwell, the writer behind <em>The Tipping Point</em> and <em>Outliers</em>, spoke about a question that intrigued me. Why can an idea that appears to work take so long to become an ordinary part of life?</p><p>We tend to imagine a fairly direct journey. Someone discovers a better way to solve a problem, demonstrates the result and persuades others to follow. The stories he told about policing and heart surgery made me think about what happens after that persuasion. People may know about an approach, accept its promise and even try it, yet struggle to make it part of dependable everyday work.</p><p>I am currently exploring how AI can help us build software differently, so the question feels close to home. Seeing what a tool makes possible is exciting. The harder task is creating the skills, working relationships and support that let people use it well over time. Making a new approach work requires changes in an organisation, but also in how people understand their place within it. That feels especially important when I am one of the people asking them to change.</p><h3>A promising idea can have a long journey</h3><p>In Boston, criminologist David Kennedy helped develop the work that led to Operation Ceasefire. Conversations with officers and people in the community revealed that much of the violence centred on relatively small networks of people. Knowing who was involved, and how one shooting could lead to another, offered a more focused way to intervene.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZvBDceVa7ecmQED-7oLjoA.png" /></figure><p>Boston began implementing Operation Ceasefire in 1996. It targeted illicit firearms trafficking and violent gangs, with direct messages that further violence would bring enforcement. An <a href="https://nij.ojp.gov/library/publications/reducing-gun-violence-boston-gun-projects-operation-ceasefire">evaluation published by the US National Institute of Justice</a> associated the intervention with a 63 per cent reduction in the average monthly number of youth homicide victims. By the early 2000s, there was published evidence that this approach could make a substantial difference.</p><p>Now move forward to January 2022. Baltimore launched a Group Violence Reduction Strategy in its Western District, combining targeted enforcement with offers of support for people at high risk of involvement in shootings. A <a href="https://penntoday.upenn.edu/news/criminology-crime-and-justice-policy-lab-baltimore-gvrs">University of Pennsylvania evaluation</a> estimated that homicides and shootings were about 25 per cent lower over the first eighteen months than they would otherwise have been.</p><p>About twenty-six years separate Boston’s initial implementation and the launch of that Baltimore programme. But Baltimore had not spent those years unaware of the idea. According to the <a href="https://abell.org/wp-content/uploads/2022/02/2021_Abell_annual-report_FINAL_0.pdf">Abell Foundation’s account</a>, the city had already attempted the approach in the late 1990s and again in 2014. Other cities had used it too. The 2022 programme was a renewed effort to turn a known approach into something that could work and last.</p><p>That makes the difficulty more revealing. In a <a href="https://content.govdelivery.com/accounts/MDBALT/bulletins/389799a">2024 statement</a>, Baltimore’s administration attributed the earlier failures to insufficient leadership commitment, implementation resources and services for people seeking to leave violence behind. This was the administration’s explanation of those failures, but it identifies needs that greater awareness alone could not meet.</p><p>Baltimore knew about the approach and had tried it. Another explanation of its benefits would not, by itself, supply the leadership, resources and working relationships that earlier attempts had lacked. Decades after the early evidence of promise, the work of making it dependable was still being done. Surgery offers a different view of what that work can ask of the people involved.</p><h3>Thirty years, and still a small minority</h3><p>Cardiac surgeon John Puskas faced a similar frustration with minimally invasive bypass surgery. Surgeons had been developing these approaches since the 1990s. Roughly thirty years later, he estimated that only two or three per cent of bypass operations at major US hospitals used minimally invasive techniques. He doubted he would live long enough to see the figure reach 50 per cent.</p><p>His frustration is easy to understand. He had spent decades pursuing a different way to operate, yet believed it remained a small part of everyday practice. His frustration concerned the distance between performing the operation successfully and helping other teams make it part of their practice.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gXgN8AR0KBJrYI6UosHkIw.png" /></figure><p>The change reached into the relationships around the operating table. In conventional surgery, the surgeon had direct access to the heart, and an experienced team could anticipate much of the work through familiar routines and cues. With the smaller openings and instruments Puskas described, the surgeon could no longer obtain all the same information directly. Colleagues had to supply information and coordinate their movements much more closely.</p><p>Surgery was already a team activity. What changed was how visibly the surgeon depended on the rest of that team. A highly experienced person could no longer rely on seeing everything for themselves. They had to listen to what a colleague could see, adjust what they were doing and trust the information being passed to them in the middle of the operation.</p><p>The change worked in both directions. Other team members had to become more active in communicating what they noticed, rather than relying so heavily on the surgeon’s familiar cues. For the surgeon, listening became part of exercising control. For colleagues, speaking became part of taking responsibility. Each person’s ability to do the work depended on the others learning those habits too.</p><p>Puskas’s concern was therefore whether he could bring an entire team through the transition, train its members, retain them and keep them committed to a way of operating he described as harder for them and better for patients.</p><p>This is the part I find most revealing. Explaining the advantages could give the team a reason to begin. It could not give them the shared experience needed to work differently under pressure. Nor could it settle how an accomplished surgeon would feel about becoming more dependent on colleagues. The equipment, the working habits and the experience of being the expert were changing together.</p><p>The story also leaves a practical question. If changing the work requires changing a whole team’s habits, what support makes that possible? Singapore’s experience with container shipping offers a different setting in which that preparation was deliberately organised.</p><h3>A port has to change around the container</h3><p>The attraction of container shipping is easy to picture. Goods can stay inside a box while the box moves between different forms of transport. But a box alone does not provide a working transport system. Ships, cranes, storage areas and the movement of cargo through the port have to fit together.</p><p>In 1966, Singapore decided to build its first container terminal. According to <a href="https://www.globalpsa.com/heritage-tab/">PSA’s history</a>, no shipping line had yet committed to building container ships for the Europe–Far East route. The first container berth opened at Tanjong Pagar in June 1972. Singapore was preparing for a change whose regional future was still uncertain.</p><p>Opening the berth made container handling possible. Expanding it meant changing the work of the port. In a <a href="https://www.nas.gov.sg/archivesonline/data/pdfdoc/19800324_0001.pdf">1980 speech on workers’ response to containerisation</a>, PSA chairman Lim Kim San reported that containerised general cargo had reached 40 per cent of PSA’s general cargo in 1979. Seven years after the terminal opened, the transition was well under way, with further growth expected.</p><p>His account also described apprehension about job losses. He said no worker had been made redundant as a result of containerisation, and pointed to systematic training and union support in helping workers move into the new work. That is evidence of a transition being actively managed, with concerns about livelihoods addressed alongside the introduction of equipment.</p><p>Singapore committed early, and carrying out that commitment required years of coordinated work. Training helped workers learn the new tasks, while assurances about employment addressed their concerns about the future. Both gave people a place in the port that was emerging. More publicity about the advantages of containerisation could not have done either job.</p><p>Software can seem exempt from this problem because it does not require a new quay or a fleet of ships. A development tool can be installed quickly, and a team can learn the outline of a method in a workshop. But what happens when the method asks them to make decisions that their organisation is not yet ready to support? The experience of agile brings that difficulty closer to my own work.</p><h3>What agile asked people to become</h3><p>When the <a href="https://agilemanifesto.org/history.html">Agile Manifesto appeared in 2001</a>, it expressed a straightforward approach to building software. Teams would build in small steps, work closely with the people using the software and change direction as they learnt. Instead of waiting until the end of a long project to discover whether they had built the right thing, they would find out along the way.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DJytYhhGcDiP0s__50NdDw.png" /></figure><p>For a manager responsible for a budget and a delivery date, this changes what it means to do the job well. A conventional project rewards keeping work on an agreed course. Agile asks the team to act on what it learns, even when that means revising an earlier commitment. The manager may welcome the approach while still answering to colleagues who need firm dates and leaders who expect the original plan to hold.</p><p>Singapore’s experience shows how much had to change around the people doing this work. The Infocomm Development Authority <a href="https://www.tech.gov.sg/media/singapore-government-projected-to-invest-1-billion-in-infocomm-technologies/">announced plans for an agile development tender in 2013</a>. By 2017, <a href="https://www.tech.gov.sg/technews/project-digital-citizen-customer/">GovTech, Singapore’s Government Technology Agency, was describing the shift</a> from managing technology contracts towards building the technical skills to develop services within government.</p><p>The ability to build was only part of what teams needed. They also needed ways to fund work whose direction could change as they learnt. In 2019, GovTech <a href="https://www.tech.gov.sg/technews/digital-government-smart-nation-pursuing-singapore-tech-imperative/">outlined changes to funding arrangements</a> to support digital development and experimentation.</p><p>Let’s pause a bit on the shift from contract management to developing services. Imagine being accustomed to checking whether a supplier has delivered what was agreed. Now you are expected to question whether the agreed feature is worth building at all. You need to understand users, discuss alternatives with engineers and sometimes recommend abandoning work that already has approval.</p><p>That calls on a different kind of judgement. A clear specification once helped demonstrate that you had done your job. Now part of doing it well involves discovering where the specification is wrong. If budgets and performance reviews still reward adherence to the original plan, accepting the case for agile does little to resolve your daily predicament.</p><p>I joined GovTech in 2023 and now serve as its chief technology officer, so these developments predate my time. I read those dates as a record of building the conditions for a different way of working. Knowing the principles of agile was useful, but teams also needed technical capability, permission to reconsider decisions and funding that allowed them to learn as they went.</p><p>These examples make me cautious about treating a difficult implementation as a failure to understand the benefits. The missing piece might be resources, time to practise or authority to make a different decision. Finding out which one is missing matters more than repeating the case for change.</p><p>There can also be a more personal difficulty within that same process. A new working arrangement may be well supported and still unsettle someone because it changes how they earn respect or experience satisfaction. Professional identity can shape how people learn and work together, even when they agree that the change is worthwhile.</p><h3>What we are being asked to give up</h3><p>Imagine spending twenty years becoming good at something. You have worked through difficult cases, made mistakes, learnt from people you admire and eventually become someone others turn to. You know what you contribute, and other people know it too.</p><p>Then a new way of working changes the terms. Some decisions you once made are shared. A skill that used to distinguish you becomes easier for others to perform. You are still needed, but it is less obvious what people need you for. Understanding why the organisation wants to change does not immediately supply an answer.</p><p>There is a useful distinction between improving a familiar way of working and changing the work itself. These are not separate categories with a clean boundary. A new tool might save a few steps, or it might gradually change which decisions we make, whom we depend on and what others value in our contribution. As those relationships change, people need opportunities to practise the new role and discover how their experience still helps. A course can support that learning, but it cannot supply all of it.</p><p>The surgeon’s growing dependence on colleagues captures something I find uncomfortable. Experience often brings the satisfaction of needing less help. Being asked to rely more on others can feel like moving backwards, even when it allows us to do better work. I would like to think I welcome a colleague’s correction, but being recognised as the expert creates its own pressure to appear self-sufficient.</p><p>A profession gives us several things at once. There is the satisfaction of being good at something, and the recognition that comes when other people know we are good at it. There is also the feeling of belonging among people who share our habits, language and standards. Over time, these become bound up with our sense of why the work is worth doing.</p><p>A change can leave that larger purpose intact while disturbing much of what makes the job rewarding from day to day. An engineer still wants to build something useful, and a manager still wants a team to deliver good work. Those ambitions tell us little about how they will feel when their own contribution changes.</p><p>Imagine telling a pianist that they can remain in music, with the same income and job security, but will now spend most of their time selecting and evaluating performances generated by software. Some would enjoy that work. Others would feel they had lost the activity that brought them into the profession. Pointing out that the audience still gets music misses a large part of the experience.</p><p>For me, this is a blind spot in the way we talk about productivity. We count what comes out of the work and pay much less attention to what the person gets from doing it. I do not think every enjoyable task deserves protection from automation. But I am reluctant to call time spent making something wasted simply because there is now a faster route to the result. Work is also how we spend our attention, what we practise and the kinds of difficulty we find satisfying.</p><p>How our colleagues react matters as well. If the people we respect regard a new method as a shortcut, using it can make us feel less like one of them. Someone might privately admire what a tool can do while avoiding it at work because they do not want to be seen as less serious about their craft. Their own opinion of the technology is only one influence on the decision.</p><p>These changes happen at different speeds. A tool can be installed in an afternoon, and its basic operation learnt in a few days. Becoming confident in a changed role requires experience. People need to make decisions, see what follows from them and discover which parts of their earlier expertise still help. One successful attempt may be encouraging without being enough to trust themselves with the next difficult case.</p><p>Recognition takes time too. Colleagues may continue seeking the kind of help someone used to provide, while overlooking their newer contribution. A manager may praise careful review but still give the most interesting assignments to whoever produces work fastest. Until the new contribution earns respect repeatedly, it can feel like a temporary departure from the real job.</p><p>This can leave a person practising two roles at once. They are learning the new work while remaining the dependable expert in the old work. The more useful they have been, the harder it may be for the organisation to release them from those expectations. A training course cannot resolve that conflict.</p><p>This is why the passage of time tells only part of the story. Repeated attempts help when people can learn from them and change the conditions that made the work difficult. If they return to the same expectations and constraints each time, another year may leave them no better prepared.</p><p>The AI changes I am pursuing could affect precisely those sources of satisfaction. Some of the work we can delegate is work people chose this profession to do.</p><h3>The changes I am asking for</h3><p>Through an experimental lab in GovTech, I am exploring what these changes could mean in practice. We are looking at what happens when an individual, or a small team with different skills, uses AI agents, systems that can carry out tasks such as writing and checking code, to take on more of the work involved in building a product. That could extend from deciding what to build and writing the software to checking it and keeping it running.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JxPIbLtOyU_vhhlcnno5Ew.png" /></figure><p>The attraction is easy to understand. Someone with a useful idea might be able to take it further, with fewer handovers along the way. We are designing ways to test a role in which the person leading a product defines an acceptable result, gathers evidence that it works and takes responsibility for keeping it running. Specialist help and backup cover would be part of making that role workable.</p><p>A working product should be able to survive its creator taking a holiday. That is a useful test of what lies beyond a fast demonstration. Can a colleague understand the software and look after it? What happens when requirements change or something goes wrong? The person leading the work needs enough understanding to check it and seek help, while the team needs a way to share responsibility without leaving that person permanently available.</p><p>That could change where someone finds satisfaction in the job. Taking pride in the whole product might become more important than having personally made each part of it. The benefit to the organisation may be clear before we understand how demanding, or rewarding, that working day will be.</p><p>Some engineers may welcome that breadth. Others may prefer depth in a particular discipline. I do not yet know how much of that difference comes from unfamiliarity, and how much reflects a lasting preference for a different kind of work. The experiment needs to leave room to discover both.</p><p>A role can make sense on an organisational chart while being a poor fit for the person asked to do it.</p><h3>AI reaches into the craft</h3><p>I feel that tension most clearly when I consider my own attachment to programming. Would I still call myself a programmer if I wrote very little of the code? My first answer is yes. Understanding the problem, deciding how a system should behave and taking responsibility for it are substantial parts of programming. Yet that answer leaves something unresolved. Knowing that the contribution remains valuable does not guarantee that the daily work will feel equally satisfying.</p><p>I do not see much point in defending manual coding as a test of professional purity. I also do not want to pretend that producing a working system and enjoying the process of writing it are interchangeable pleasures. It is perfectly possible to appreciate the speed and miss the work.</p><p>That reaction is easy to mishandle. We tell the programmer they are being freed for higher-value activities. We may mean that their time can now produce more for the organisation, but that says little about which parts of the job they enjoy. The phrase offers little comfort if the supposedly lower-value activity was the part they loved.</p><p>Reviewing generated code brings its own difficulties. The solution may use an approach I would never have chosen, leaving me to work out whether its unfamiliarity hides a problem or simply reflects a different way of thinking.</p><p>There is substantial work in making that assessment. I need to understand what the software is supposed to do, what other systems it relies on and what could happen if it fails. Calling this a move towards judgement, creativity and strategy tells me little about what an ordinary Tuesday will feel like. It can sound suspiciously like a job description from which all the actual tasks have been removed.</p><p>Managers face their own adjustment. If someone junior can produce a persuasive analysis quickly, seniority becomes less reliable as a proxy for who has the best answer. Experience can still help distinguish a sound conclusion from an attractive mistake, but it has to demonstrate its value through that distinction.</p><p>The temptation is to restore familiar authority by controlling access, requiring unnecessary approvals or treating all machine-assisted work as suspect. The opposite temptation is to abandon judgement and celebrate output simply because it was produced quickly. Neither response helps people develop a respected, demanding practice around the tools.</p><p>For people entering the profession, there is a further difficulty. We are asking them to judge work that they may have had fewer opportunities to do for themselves. An experienced engineer can draw on years of trying things, finding mistakes and fixing them. If AI takes over much of that early work, a junior colleague needs another way to develop the understanding we expect them to use.</p><p>This is a question I do not think we can answer simply by telling people to review everything carefully. They need to learn what careful review involves. A team might ask a learner to explain how a proposed solution works, predict where it could go wrong and compare it with another approach before accepting it. An experienced colleague could then explore the reasoning with them. The exercise would reveal what the learner understands, even if generating the solution took only a few minutes.</p><p>That takes time from experienced engineers. If we count only the speed of today’s delivery, it will be easy to neglect the people expected to take responsibility for tomorrow’s systems.</p><p>Part of developing that judgement is learning when to challenge a proposed use of the technology. A person who identifies a privacy problem, a misleading result or an unacceptable failure rate is providing information. Calling every objection resistance to change makes the identity argument into a convenient way to stop listening.</p><p>This is where I put a limit on the identity explanation. The person slowing a rollout may be protecting an old role. They may also have found the failure everyone else has missed. The useful response is to examine the concern and establish what evidence would resolve it. If I want engineers to take responsibility for agent-generated work, I have to respect their willingness to question it, including when that questioning slows a result I want.</p><h3>Making the new role worth having</h3><p>If careful questioning is part of the work we want, people need to see that it counts in decisions about their careers. Otherwise the message to an engineer is confusing. Be thorough, but keep up with colleagues who appear to deliver much faster.</p><p>We need to recognise the engineer who spots that a requested feature would make the service harder to use, or catches a design mistake before the team builds more software around it. Making a product understandable enough for another team to take over matters too. These contributions are less visible than generating a large amount of code. If I celebrate speed at every opportunity and discuss quality only when something breaks, people will notice where my attention goes.</p><p>That recognition needs to reach decisions about promotion, assignments and how people spend their time. An engineer helping a colleague develop judgement should not have to explain it as a failure to produce enough of their own work. Someone who establishes that an experiment should stop has contributed, even if there is no launch to celebrate.</p><p>People also need opportunities to practise with help close at hand. For the roles we are exploring, we are considering a period of working alongside someone experienced before taking independent responsibility. That would let people talk through difficult decisions and gradually discover what they can handle themselves. For an experienced practitioner, being able to ask a basic question without putting their whole reputation on trial may be particularly valuable.</p><p>Practice needs clear boundaries when a live service is involved. Learning when to seek review or stop an agent is part of learning the role. I want the lab to help us understand what support a team needed, what remained difficult and whether someone else could repeat the work. Those lessons would give the next team more than a prototype to admire.</p><p>We also need to listen when the role is not working for someone. A broader job may turn out to be exhausting, or contain less of the activity they enjoy. Concern about employment or workload needs a concrete answer. It cannot be resolved by telling people to think differently about their identity.</p><p>I do not think leaders should require a performance of enthusiasm before offering help. Someone who misses doing the work themselves is giving us information about the job we are creating. We may be able to adjust the balance of tasks or find another application for their strengths. Where change is necessary, the disappointment still deserves to be heard.</p><h3>Learning to be a beginner again</h3><p>I keep thinking about the story of Gladwell’s father, a mathematician who approached problems with enjoyment and mischief. Before showing his son the expected way to solve a homework problem, he would explore an unusual way of doing it. He also tried things outside his expertise, including playing the piano and keeping bees, without needing to be especially accomplished at them.</p><p>What appeals to me about that story is its sense of enjoyment. Much of the discussion about change concerns what people might lose. His father’s example suggested something we might recover, the pleasure of trying without having to prove ourselves. Being good at one thing need not prevent us from enjoying being ordinary at another.</p><p>I would like there to remain some part of my working life where I can do that. There is a trap in becoming experienced. You grow accustomed to feeling competent and begin arranging your life around situations that preserve the feeling. Eventually, the desire to remain good at things can make you reluctant to begin anything new.</p><p>For my own work, curiosity means staying interested when an experiment gives an unwelcome answer. A role I favour may prove unworkable. Someone whose hesitation frustrates me may have recognised a difficulty I missed. I need to ask what support was missing and whether the work itself needs to change, without making the answer a verdict on my worth as a leader.</p><p>It is easy to admire adaptability while the change is happening to somebody else’s profession.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=274436d0a42a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Can Jev play Space Invaders?]]></title>
            <link>https://medium.com/@sausheong/can-jev-play-space-invaders-b9b592d5431e?source=rss-a358058b2410------2</link>
            <guid isPermaLink="false">https://medium.com/p/b9b592d5431e</guid>
            <category><![CDATA[golang]]></category>
            <category><![CDATA[videogames]]></category>
            <category><![CDATA[jevs]]></category>
            <category><![CDATA[typesafe-ai]]></category>
            <category><![CDATA[ai]]></category>
            <dc:creator><![CDATA[Sau Sheong]]></dc:creator>
            <pubDate>Tue, 29 Sep 2026 16:47:29 GMT</pubDate>
            <atom:updated>2026-09-29T16:47:29.995Z</atom:updated>
            <content:encoded><![CDATA[<h4>Going back to my Space Invaders game, and letting Jev have a turn</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pjn0yNn9ge2hp9wEgjj5NA.png" /></figure><p>In 2018 I wrote <a href="https://medium.com/sausheong/create-a-simple-cross-platform-desktop-game-with-go-8e5432128c9b">Create a simple cross-platform desktop game with Go</a>. I took a terminal Space Invaders game I had made earlier and turned it into a desktop app. Go drew each frame as an image, a local web server served it, and a tiny library called webview put it in a window. Fetch the images quickly enough and you had a game. It was a fun little project to fiddle around.</p><p>Eight years later, I opened the project again. It didn’t build.</p><p>This is one of the less charming forms of software nostalgia. The aliens had patiently waited for me, but the dependencies had moved on. I decided to get it running again, tidy up the game, and then hand the controls to <a href="https://docs.typesafe.ai/introduction">Jev</a>, TypeSafe’s decision model.</p><p>Getting the aliens back on screen was the easy part. Getting Jev to stop driving into their bombs took rather longer.</p><h3>Getting the aliens back</h3><p>The old project had no go.mod, and its webview and audio dependencies needed replacing. I added a module targeting Go 1.26, moved to <a href="https://github.com/webview/webview_go">webview_go</a> and <a href="https://github.com/gopxl/beep">gopxl/beep/v2</a>, and kept gift for image processing. jQuery and the unused Bootstrap dependency could retire.</p><p>The most satisfying removal was the web server. In the original app, the page polled /frame for images and sent key presses to /key. There was even a cache workaround for the old Windows browser engine, which otherwise liked the first frame so much it kept showing it.</p><p>The current webview package has Bind, which exposes a Go function to JavaScript. The page can ask Go for a frame directly, without an HTTP server in between. This is the frame binding from the new app.</p><pre>w.Bind(&quot;frame&quot;, func(seq uint64) map[string]any {<br>	s, src := game.CurrentFrame()<br>	if s == seq {<br>		return map[string]any{&quot;seq&quot;: s, &quot;src&quot;: &quot;&quot;}<br>	}<br>	return map[string]any{&quot;seq&quot;: s, &quot;src&quot;: src}<br>})</pre><p>Each frame has a sequence number. If the page already has the latest one, Go returns an empty image string. Otherwise it returns the new image. A small JavaScript loop calls this through requestAnimationFrame, while two more bindings pass key-down and key-up events to Go.</p><p>The browser side is small enough to show almost in full. The frame function below is the Go function bound above, exposed as an asynchronous JavaScript call.</p><pre>async function loop() {<br>  try {<br>    var f = await frame(seq);<br>    seq = f.seq;<br>    if (f.src !== &#39;&#39;) img.src = f.src;<br>  } catch (e) {}<br>  requestAnimationFrame(loop);<br>}<br>requestAnimationFrame(loop);</pre><p>The returned image is a PNG data URI, so the page can assign it straight to an image element. The game loop produces frames independently of the page asking for them. If the page asks twice before the next frame is ready, the sequence number saves it receiving the same image twice. There is no need to make the game simulation run at the browser’s refresh rate.</p><p>Go still draws the pictures and the webview still shows them, but the plumbing no longer needs its own web server. With that gone, I turned to another small inconvenience left over from 2018.</p><p>I embedded the images, sounds and HTML with //go:embed. The old version looked for assets next to the executable, which was awkward when go run put that executable in a temporary directory. Now the assets travel inside the binary, and this works from a checkout with Go and the native build dependencies installed.</p><pre>go run ./cmd/invaders</pre><p>The binary still uses the operating system’s webview and audio facilities, but there is no separate asset folder to lose. Sound playback got a similar cleanup. The speaker is initialised once and the three WAV files are decoded into memory at startup, rather than reopened and decoded whenever something shoots or explodes.</p><p>There are only three effects to worry about, for shooting, an alien being killed, and an explosion. Once decoded, each sits in a buffer that can supply a fresh audio stream whenever it is needed. If the audio device cannot be initialised, the game carries on silently. The invasion should not have to wait for my speakers.</p><h3>While I was in there</h3><p>With the pictures and sounds working again, I could finally play. This was when I discovered that my younger self had left me a few things to do.</p><p>The cannon could drive off the screen, destroyed aliens still influenced when the formation turned around, and bombs kept falling forever after disappearing off the bottom. Clear every alien and you were rewarded with an empty screen that carried on being empty. Apparently I had not planned for anyone to be good at it.</p><p>There were less visible problems too, including unsynchronised state shared between the game loop and the old web handlers, and a collision check that used one sprite’s dimensions for both objects. That explained a few suspicious hits. For once, blaming the game was justified.</p><p>Once I had fixed those, adding lives and another wave seemed reasonable. Then it seemed a shame not to have shields. You can probably see how this went.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/799/1*7SUrM6u5H2MN4Npn1xIdrA.jpeg" /><figcaption><em>The renovated game running in its desktop window, with the full playfield visible. Three lives, four shields, and quite a lot of aliens to negotiate with.</em></figcaption></figure><p>The cannon now moves smoothly while a key is held, with the game loop targeting 50 updates a second. There are three lives, a score, a saved high score, and proper title and game-over screens. The aliens speed up as their numbers fall, and clearing a wave starts another one, lower and faster.</p><p>That change to movement makes a noticeable difference. The old cannon moved a fixed distance for each key event, so holding an arrow depended on the operating system’s key-repeat behaviour. Now a key-down means “start moving” and a key-up means “stop”. The game checks that held state on each update. You get continuous movement rather than a cannon that appears to be negotiating each step with the keyboard.</p><p>I added four destructible shields, bombs dropped by the lowest alien in each column, and a mystery UFO worth 50 to 300 points. You can pause with p, which is an advantage the aliens have graciously agreed to give you.</p><p>The code also outgrew its original two-file arrangement. The game rules and drawing now live in internal/game, embedded assets in internal/assets, and window setup in cmd/invaders. Separating the simulation from the window means I can test the rules without opening the app. A rendering test can also produce screenshots using the game&#39;s own drawing code. The full-window screenshot above was captured from the running app.</p><p>By then the renovation had produced a pleasant little game and a convenient way to give another player access to its state. That brought me back to Jev.</p><h3>Giving Jev the controls</h3><p><a href="https://docs.typesafe.ai/introduction">Jev</a> is what TypeSafe calls a System One model. You give it a state and typed questions, and it returns structured decisions rather than a written response. A <em>Choice</em> question selects from options you supply, a <em>Noul</em> question returns a probability for a yes/no proposition, and a <em>Score</em> question rates something against a rubric. Questions can share a state in one request while being evaluated independently.</p><p>For Space Invaders, Choice and Noul covered the two decisions I needed. Where should the cannon go, and should it shoot? It seemed a manageable first day at work.</p><p>In this integration, Jev receives text descriptions, not screenshots. Go reads the game state and turns it into words. Jev chooses an action, and Go carries it out. I didn’t train or fine-tune a model for the game.</p><p>There’s no Go SDK for TypeSafe, but the API is a single endpoint, so the client is short. A request carries a state, a model name and a map of named questions. The answers come back under the same names.</p><pre>type Question struct {<br>	Type         string `json:&quot;type&quot;`         // &quot;choice&quot;, &quot;noul&quot; or &quot;score&quot;<br>	Instructions any    `json:&quot;instructions&quot;` // plain text, or JSON with named parts<br>	Criteria     any    `json:&quot;criteria,omitempty&quot;`<br>}<br><br>type Answer struct {<br>	Choice        string             `json:&quot;choice&quot;`        // Choice: the option picked<br>	Probabilities map[string]float64 `json:&quot;probabilities&quot;` // Choice: every option&#39;s probability<br>	Confidence    float64            `json:&quot;confidence&quot;`<br>	Noul          float64            `json:&quot;noul&quot;`          // Noul: probability of yes<br>}<br><br>answers, err := client.Ask(ctx, state, questions)</pre><p>Ask marshals the state and questions, adds &quot;model&quot;: &quot;jev-latest&quot;, and posts them to https://api.typesafe.ai/v1/systemone with the API key as a bearer token. If the service says it&#39;s rate limited or overloaded, it waits half a second and tries once more. Everything interesting happens in what goes into state and questions.</p><p>This gives it a different view from the human player. I have to look at the screen and judge whether a bomb is heading towards me. The autopilot gets a snapshot containing the cannon, live aliens, bombs, remaining shields and the UFO, along with the formation’s movement timing. Go can work with those exact positions before writing a description for Jev. So this is an experiment in choosing actions from prepared information, rather than learning to recognise Space Invaders from its pixels.</p><p>The game itself knows nothing about TypeSafe. It exposes an Autopilot interface with a snapshot of the game, input controls and events such as a cannon hit or a shot ending. The Jev implementation lives in a separate package and is wired in only when I build with the jev tag.</p><p>The interface is deliberately small.</p><pre>type Autopilot interface {<br>    Input(v View, in Input) Input<br>    Observe(v View)<br>    Event(ev Event, fromPilot bool)<br>    HUD() (top, bottom string)<br>}</pre><p>Before each simulation step, Input can supply movement and firing controls. Afterwards, Observe receives a fresh snapshot. Event reports what happened, and HUD supplies the status text drawn in the screen corners. The snapshot contains copies of the relevant state, so the background work can read it without reaching into objects the game loop is changing.</p><p>That boundary also keeps the API out of the game loop. The aliens continue moving while a request is in flight. Pausing the universe until Jev replied would certainly improve its chances, but it would make for a rather different game.</p><pre>go build -tags jev -o invaders ./cmd/invaders<br>TYPESAFE_API_KEY=... ./invaders -jev</pre><p>A normal build leaves the Jev implementation out. In a Jev build, pressing j switches the autopilot on or off, so I can take over whenever I think I can do better. Whether I can is a separate question, conveniently absent from the logs.</p><h3>Left, right, or straight into a bomb</h3><p>With the controls connected, I needed to decide what to tell Jev. I started with the sort of running commentary you might give someone learning the game. Go described the danger here, to the left and to the right, along with the nearest alien and whether the laser was ready. A typical description looked like this.</p><pre>{<br>  &quot;cannon_position&quot;: &quot;away from the walls&quot;,<br>  &quot;danger_here&quot;: &quot;a bomb is falling onto this spot and will hit very soon&quot;,<br>  &quot;danger_left&quot;: &quot;clear: no bomb is falling onto this spot&quot;,<br>  &quot;danger_right&quot;: &quot;a bomb is falling onto this spot but is still high up&quot;,<br>  &quot;line_of_fire&quot;: &quot;an alien&quot;,<br>  &quot;laser&quot;: &quot;ready to fire&quot;,<br>  &quot;nearest_alien&quot;: &quot;an alien is a little to your left&quot;<br>}</pre><p>Jev chose left, right or stay, and answered whether to fire. A background goroutine sent requests one after another, while the game carried on using the latest answer.</p><p>Those were two questions in the same request, shown here slightly trimmed. The names in backticks refer to fields in the state above, which is how TypeSafe lets a question point at a particular piece of it.</p><pre>questions := map[string]typesafe.Question{<br>	&quot;move&quot;: {<br>		Type:         &quot;choice&quot;,<br>		Instructions: &quot;Which way should the cannon move right now? Staying alive comes first: never stay in, or move into, a spot where a bomb will hit very soon. When you are safe, move toward `nearest_alien`.&quot;,<br>		Criteria: map[string]string{<br>			&quot;left&quot;:  &quot;Move left. Choose this when `danger_here` says a bomb will hit very soon and `danger_left` is clear, or when you are safe and `nearest_alien` is to your left.&quot;,<br>			&quot;right&quot;: &quot;Move right. ...&quot;, // the mirror image of left<br>			&quot;stay&quot;:  &quot;Stay where you are. Choose this when `danger_here` is clear and `nearest_alien` is directly above you, or when moving either way would lead into a bomb that will hit very soon.&quot;,<br>		},<br>	},<br>	&quot;fire&quot;: {<br>		Type:         &quot;noul&quot;,<br>		Instructions: &quot;Should the cannon fire its laser right now?&quot;,<br>		Criteria: map[string]string{<br>			&quot;true&quot;:  &quot;`laser` is ready to fire and `line_of_fire` is an alien or the mystery UFO.&quot;,<br>			&quot;false&quot;: &quot;`laser` is not ready, or `line_of_fire` is nothing or your own shield.&quot;,<br>		},<br>	},<br>}</pre><p>The Choice answer names one option, with a probability for each. The Noul answer is a probability that the cannon should fire, and the code fires above 0.5.</p><p>The first danger descriptions covered the cannon’s current position and strips 30 pixels to either side. “Very soon” meant a bomb was less than 0.7 seconds from impact. Those phrases were translations of calculations done in Go. Jev didn’t have to subtract coordinates or convert pixels into seconds, but it did have to choose from the picture those phrases painted. Anything outside that picture might as well not exist.</p><p>Before letting it loose, I tried ten hand-built situations against the API. Jev got nine right. In the tenth, it moved towards an alien on the left even though a bomb was about to land there.</p><p>My instruction allowed a left move when the cannon was safe and the nearest alien was to the left. I had meant that the move should be safe, but what I had written only said the cannon was safe where it currently stood. Jev had followed my instructions into a bomb. This was awkward for my plans to blame Jev.</p><p>I rewrote the condition to require danger_left to be clear before moving left. The same ten scenarios then passed.</p><pre>// before<br>&quot;left&quot;: &quot;Move left. Choose this when `danger_here` says a bomb will hit very soon and `danger_left` is clear, or when you are safe and `nearest_alien` is to your left.&quot;,<br><br>// after<br>&quot;left&quot;: &quot;Move left. Choose this only when `danger_left` is clear, and either `danger_here` says a bomb will hit very soon or `nearest_alien` is to your left. Never choose this when `danger_left` says a bomb will hit very soon or is the wall.&quot;,</pre><p>The distinction was small enough to miss in prose but large enough to drive a cannon through. “You are safe, so move towards the alien” and “move towards the alien only if the way is clear” allow different actions. The test was useful because I could inspect the exact words behind the mistake instead of vaguely asking the model to be more careful.</p><p>Ten out of ten looked encouraging. The aliens were about to provide a larger sample.</p><h3>Good advice, delivered late</h3><p>To find out how those tidy test scenarios translated into actual play, I added a decision log. It recorded what Jev had been told, what it chose and what happened afterwards. Each movement decision was followed for one second, and each shot was tracked until it hit something, missed or was cancelled. The autopilot could also start another game by itself, which made it very efficient at collecting evidence against my first design.</p><p>In the first session, covering 683 decisions over roughly three minutes, half the completed shots hit a target. The cannon was lost about every six seconds. Twenty-nine shots hit its own shields.</p><p>The log made the shooting failures particularly puzzling. Jev was saying “fire” when the description said an alien was in the line of fire. It was choosing sensibly from the information I had supplied, so I looked at what happened between sending that information and pulling the trigger.</p><p>Requests in these sessions generally took about 250–450 ms. At around 300 ms, the cannon could travel 45 pixels while Jev was answering. By the time “fire” arrived, it described a shot from somewhere the cannon had already left. Good advice, wrong address.</p><p>The movement descriptions had a similar problem. My left and right danger zones covered only 30 pixels. The cannon could drive beyond that neighbourhood before the next answer arrived, meeting a bomb Jev had never been told about.</p><p>At 50 updates a second, a 300 ms request spans about 15 game updates. During those updates, the cannon moves, bombs fall and the aliens continue across the screen. “Shoot now” therefore needs a fairly precise definition of “now”. Mine had accidentally meant “a little while ago, when this would have been a good idea”.</p><p>So I checked the line of fire again before applying a fire decision, widened the danger zones to 50 pixels, and warned about approaching bombs earlier. Shots into our own shields fell from 29 to one in the next run. Over a longer, 15-minute session, shot accuracy settled at 61%.</p><p>Better. Still a lot of ammunition going into space, even by the standards of the game.</p><h3>Asking a better question</h3><p>Wider danger zones helped, but they left the basic arrangement unchanged. I asked Jev which direction to move, then let the cannon keep going until another answer arrived. I was giving it a steering wheel with a delay and wondering why it kept having accidents.</p><p>There was a way to give it less driving to do. This was my game. I knew how fast the cannon moved, how fast bombs fell, and how the alien formation stepped across the screen. Go could calculate possible journeys before Jev chose one.</p><p>So I changed the question from “left, right or stay?” to “which spot should you go to?”</p><p>The code now lists roughly 20 destinations across the screen. For each one, it simulates the cannon continuing towards its current destination during the estimated API delay, then travelling to the candidate destination. It checks that journey against the visible bombs and looks a little beyond arrival. Separately, it predicts whether a shot would meet an alien or the UFO, allowing for their movement while the laser travels upwards.</p><p>Jev gets options like this.</p><blockquote>Move a long way to the left. Safety: safe: no falling bomb will hit you on the way there or for a while after you arrive. Shooting: an alien will be in your line of fire when you get there.</blockquote><p>The options describe safe, risky and deadly trips. Jev picks one, and the code steers towards that destination, stopping when it reaches it or gets within a pixel.</p><p>Most of the information has moved out of the state and into the options themselves. The state now holds only what the fire question needs.</p><pre>{<br>  &quot;laser&quot;: &quot;ready to fire&quot;,<br>  &quot;line_of_fire&quot;: &quot;a shot fired now would hit an alien&quot;<br>}</pre><p>Each candidate spot becomes one option of the Choice question, keyed by a name the code can look up afterwards.</p><pre>options := make(map[string]string, len(o.Spots))<br>for _, s := range o.Spots {<br>	options[s.Key] = s.Text // &quot;spot_03&quot;: &quot;Move a long way to the left. Safety: safe: ...&quot;<br>}<br><br>questions := map[string]typesafe.Question{<br>	&quot;spot&quot;: {<br>		Type:         &quot;choice&quot;,<br>		Instructions: map[string]any{&quot;role&quot;: role, &quot;question&quot;: &quot;Pick the spot the cannon should go to next, following `priorities` in order.&quot;, &quot;priorities&quot;: priorities},<br>		Criteria:     options,<br>	},<br>	&quot;fire&quot;: fireQuestion,<br>}</pre><p>Reading the answers is equally plain. The chosen key maps back to a spot the code already knows the position of.</p><pre>answers, err := p.client.Ask(ctx, o.State, o.questions())<br>pick, fire := answers[&quot;spot&quot;], answers[&quot;fire&quot;]<br>for _, s := range o.Spots {<br>	if s.Key == pick.Choice {<br>		chosen = s // the code steers towards chosen.X<br>	}<br>}<br>p.fire = fire.Noul &gt;= 0.5 &amp;&amp; o.State.Laser == laserReady</pre><p>Checking the journey matters as much as checking the destination. A clear spot on the other side of a falling bomb is not much use if the cannon has to cross the bomb’s path at exactly the wrong moment. The forecast advances the cannon and bombs one game tick at a time and checks whether their rectangles overlap.</p><p>A collision before the expected answer arrives is labelled deadly because that candidate decision would come too late. A collision during the trip is also deadly. If the trip is clear but a bomb threatens the cannon soon after arrival, the spot is risky. Otherwise it is safe within the simulated window, which normally includes another 0.8 seconds after arrival, with an overall four-second cap.</p><p>The delay estimate is updated from measured response times using a moving average. It doesn’t assume the network will always take exactly 300 ms. That estimate determines how long the simulated cannon follows its existing instruction before switching to the proposed one.</p><p>“Safe” here means safe within the forecast. It cannot account for bombs that haven’t been dropped yet, and its assumptions about shields and the formation can become stale as the game changes. The simulation is useful precisely because this is a small, predictable world, but it still has a limited view of the future.</p><p>Shooting needs its own forecast. An alien above the cannon now may have moved sideways by the time the laser reaches its row. The code steps the formation forwards, including its reversal at the screen edge, and checks where the rising beam would meet it. Shields matter too, since an excellent shot at an alien is less excellent when it has to pass through your own defences first.</p><p>The fire question remains separate from the destination choice. Heading towards a promising firing position doesn’t mean the cannon should shoot immediately. Jev is also given the laser’s availability and the predicted result of firing when the answer takes effect. The two answers share a request, but serve different purposes.</p><p>With this design, shot accuracy rose from 61% to 96%, and survival after decisions made in safe situations rose to 92%. Escaping danger was still a problem, though. That figure actually fell from 76% to 72% in the recorded runs.</p><p>The cannon had become a much better shot without becoming a particularly good escape artist.</p><h3>Please stop changing your mind</h3><p>The next log helped explain why. Jev had selected an unsafe destination while a safe one was available only three times in 644 decisions. The destinations looked sensible. The trouble was getting the cannon to finish a journey.</p><p>When several spots looked equally good, Jev kept choosing a different one. The cannon zig-zagged, abandoning the route used in an earlier forecast. It had the air of someone trying to choose the shortest supermarket queue, except the queues were dropping bombs.</p><p>Confidence was often around 0.4 in these cases. TypeSafe’s <a href="https://docs.typesafe.ai/confidence">confidence documentation</a> explains that a low value can mean no option is a clear winner. It isn’t a direct probability that the cannon will survive.</p><p>Meanwhile, new bombs could appear just after a snapshot was taken. With requests sent one at a time, a bomb might wait nearly two request durations before an answer accounting for it arrived. That became painful as the aliens descended.</p><p>The delay needed attention again, so I made the requests overlap, starting one at most every 100 ms with a limit of three in flight. An answer based on an older observation than one already applied is discarded. This reduces the wait for a fresh observation, although it doesn’t make an individual request faster and can use more API calls.</p><p>For example, suppose a bomb appears just after one request leaves. With sequential requests, the autopilot waits for that answer before sending a description that includes the new bomb, then waits again for the next answer. Overlapping requests can get that new description on its way while the first request is still being processed.</p><p>The answers need not return in the order they were sent. Each observation therefore has a sequence number. If an answer about observation 42 arrives after one about observation 43 has already been accepted, 42 is ignored. Otherwise an unusually slow request could make the cannon change its mind based on an older world, which it was already doing quite enough of without help from the network.</p><p>To discourage the zig-zagging, I added an explicit “keep heading to your current destination” option. I also added an “exposed” warning for positions beneath low aliens. Those spots might be clear now, but a newly dropped bomb could arrive before the autopilot had time to react and dodge.</p><p>These preferences needed an order. Simply telling Jev to prefer staying put had produced a cannon that declined to chase an alien. I had asked it to be less indecisive and accidentally encouraged early retirement.</p><p>The revised instructions put survival first, then a chance to shoot. Jev should keep its current destination if it met both priorities, and avoid exposed positions unless they offered a shooting opportunity. If no safe spot offered a target, it could stay where it was, provided that was safe too.</p><p>The instructions accept structure, so the priorities went in as a numbered list rather than one long sentence.</p><pre>&quot;priorities&quot;: []string{<br>	&quot;1. Survive: pick a spot described as safe if there is one. If no spot is safe, pick a risky spot rather than a deadly one.&quot;,<br>	&quot;2. Attack: among safe spots, pick one where an alien or the mystery UFO will be in your line of fire, even if it is a long move.&quot;,<br>	&quot;3. Commit: if you are already heading to a spot that satisfies 1 and 2, keep heading there.&quot;,<br>	&quot;4. Avoid exposed spots unless they satisfy 2.&quot;,<br>	&quot;5. If no safe spot has an alien or the mystery UFO in your line of fire, stay where you are if that is safe.&quot;,<br>},</pre><p>The code still checks a firing answer before using it. If a laser is already in flight, it cannot launch another. If a fresh forecast says the shot would hit a different kind of target from the one described to Jev, the shot is dropped. The model’s answer is permission to try an action, with the current game state deciding whether that action still makes sense.</p><h3>How well did it play?</h3><p>After those changes, the cannon spent less time reversing and more time surviving. Across the development sessions, the figures looked like this.</p><p>I kept the game’s score separate from the measurements used to debug the autopilot. The score tells me how much damage it has done. The decision log helps explain why it stayed alive or failed. An escaped movement decision means the cannon was classified as under threat and wasn’t hit during the following second of active play. It doesn’t mean that decision alone caused the escape, since newer decisions may have taken over during that second.</p><p>The screen shows a running dodge and hit tally. Resolved decisions go into jev-actions.jsonl, with the supplied state, chosen destination, confidence, firing probability and outcomes. A separate jev-summary.txt keeps the aggregate figures. This is considerably more paperwork than I normally require from someone playing Space Invaders, but it made the failures useful.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ekCLUJJgvxqxqeWiNesuOg.png" /></figure><p>The wider-danger-zone version ran for 15 minutes. The final design was tested in shorter sessions of a few minutes each. Its shot accuracy was slightly below the first destination-based version, but the recorded survival figures were better. In the final sample, Jev chose an unsafe spot while a safe one was available once in 1,052 decisions, and selected no spots labelled exposed.</p><p>I wouldn’t read too much into a few percentage points. Bomb drops are random, the sessions differed in length, and the changing danger descriptions mean “under threat” didn’t mean quite the same thing in every version. A single cannon hit also marks all pending decisions from the preceding second as killed, so several decisions can share one unfortunate ending. Shot accuracy counts completed shots, excluding cancellations.</p><p>The figures helped me improve the autopilot, but they measure the whole arrangement, including my forecasts and shot checks. With Go already doing so much of the work, a controller written entirely in code would be a useful comparison. I haven’t tested that here. This began as a way to let Jev play an old game, and I’m not quite ready to turn the aliens into a benchmark committee.</p><p>The highest score recorded in these sessions was <strong>1,680</strong>, achieved by the earlier left/right version during its longer run. This compared to my measly powers when my highest score is 230. So the final design gets the better survival figures, while its predecessor keeps the high score. I can’t quite award it every trophy.</p><h3>Letting Jev play</h3><p>If you’d like to watch it yourself, you’ll need Go, the native webview dependencies for your platform and a TypeSafe API key. The autopilot only exists in builds made with the jev tag, so a normal build won&#39;t respond to the flag or the key described here.</p><pre>git clone https://github.com/sausheong/invadersapp<br>cd invadersapp<br>go build -tags jev -o invaders ./cmd/invaders</pre><p>The game looks for the key in three places. It first checks the TYPESAFE_API_KEY environment variable, then a .env file in the current directory containing a TYPESAFE_API_KEY= line, and finally a file called typesafe-api-key in the game&#39;s data directory. On macOS that directory is ~/Library/Application Support/invaders, next to the saved high score.</p><p>With the key in place, start the game with the autopilot switched on.</p><pre>./invaders -jev</pre><p>There’s nothing else to press. After two seconds on the title screen, the autopilot starts a game by itself, and it does the same after every game over. Left alone, it will keep playing until you close the window, which is either a triumph of automation or a very efficient way to watch aliens win.</p><p>You can also start without the flag and press j whenever you fancy a rest. Pressing j again takes the controls back. If the key can&#39;t be found, the top-right corner says so instead of quietly doing nothing.</p><p>While Jev is playing, the top-right corner shows its latest move as an arrow, its confidence in the chosen spot and how long the request took. The bottom-right corner keeps the running dodge and hit tally. The summary file is rewritten every five seconds, so you can check the figures in jev-summary.txt without stopping the game. When the window closes, including after Ctrl+C in the terminal, the final summary is printed as well.</p><p>There’s also a macOS app bundle, built with the same tag.</p><pre>scripts/build-macOS -tags jev</pre><p>An app opened from Finder can’t be given the -jev flag or see a .env file in your project folder, so save the key in the data directory and press j once the window opens.</p><p>One practical note: the autopilot makes several requests a second while a game is running, and it keeps starting new games unattended. Each request is small, but if you leave it running overnight, you are paying for a very dedicated Space Invaders habit.</p><h3>A slower evening</h3><p>I thought the story ended there. Then, in the evening as I was fiddling around with Jev and Invaders, Jev started playing badly again, dying every few seconds with the same code that had been doing well that afternoon.</p><p>The decision log pointed at the clock rather than the choices. Decisions were arriving about twice a second instead of eight or nine times. Several times, every destination on offer was marked deadly, with a bomb due to hit before any answer could take effect. Jev was left with nothing sensible to choose from.</p><p>Timing the API showed why. Requests that had taken 230–300 ms in the afternoon now took about 520 ms, and a tiny one-question request was no faster. Connecting to the service took a few milliseconds, so the time was being spent on TypeSafe’s side. Their models page does warn that capacity is adjusting to heavy demand. Answers also seemed to arrive in batches roughly every half-second, so sending more requests at once didn’t produce fresher decisions. Under those conditions, the autopilot could see the game only about twice a second. Bombs fall 200 pixels a second.</p><p>Everything I’d built so far assumed each answer would arrive in time to deal with the next surprise. At half a second, a bomb dropped close to the cannon lands before any decision about it can take effect. If I couldn’t get answers sooner, I could at least ask the question before I needed the answer.</p><p>So every request now carries a third question alongside the destination and the fire decision. If a new bomb suddenly appeared right above you, too close to wait for another decision, which way would you run? Go describes each side, including the nearest safe spot, any wall in the way and any known bombs falling there. Jev picks a direction. The answer is a contingency plan, held in reserve.</p><pre>&quot;escape&quot;: {<br>	Type: &quot;choice&quot;,<br>	Instructions: map[string]string{<br>		&quot;role&quot;:     role,<br>		&quot;question&quot;: &quot;Plan ahead: if a new bomb suddenly appears right above you, too close to wait for another decision, which way should you run?&quot;,<br>	},<br>	Criteria: map[string]string{<br>		// written fresh for every request, for example:<br>		&quot;left&quot;:  &quot;Run left. The nearest safe spot is a short dash to the left, and no known bomb is falling there.&quot;,<br>		&quot;right&quot;: &quot;Run right. The right wall is right beside you, so there is no room to run this way.&quot;,<br>	},<br>},</pre><p>On every game update, the code checks whether the cannon’s current course runs into a bomb before a fresh answer could possibly arrive. If it does, the cannon carries out the escape Jev already chose, dashing to the nearest safe spot in that direction without waiting for the network. The next answer then takes over as usual. TypeSafe’s documentation describes this as asking speculative questions, and letting code use whichever answers apply. I had read that page early on without realising how useful it would be to a laser cannon.</p><pre>// A bomb the current plan runs into before a fresh decision could<br>// arrive: carry out the escape Jev planned in advance.<br>if !p.escaping &amp;&amp; p.escapeDir != 0 {<br>	f := newForecast(v)<br>	if f.hitSoon(x, p.dest, int(p.lag.Load())+escapeMargin) {<br>		if ex, _ := f.escapeSpot(x, p.escapeDir); ex &gt;= 0 {<br>			p.dest, p.escaping = ex, true<br>		}<br>	}<br>}</pre><p>The estimated delay decides how far ahead to look. The direction came from Jev, in a request that finished before the bomb even appeared.</p><p>I ran the previous version and the new one back to back that evening, about four minutes each, under the same slow responses.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eu6TT-WoOZV_3Qu6lx39tw.png" /></figure><p>The new version lost the cannon three times in almost four minutes, where the previous one lost it about every five seconds. It wasn’t a pure improvement, though. It fired far fewer shots, and hits fell from about 27 a minute to 11. Part of that is because the previous version kept dying and starting new games with a full formation directly overhead, but the new one was also more cautious. A cannon that keeps running away is a cannon that isn’t shooting.</p><p>The other lesson was that the autopilot’s performance was never just a property of the model. The same code played very differently depending on how quickly the service answered. When the answers can’t come faster, the best move is to ask for them earlier.</p><h3>Eight years later</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/400/1*oNmfLlY0syX7VPz3OHhhRA.png" /></figure><p>Looking back, I spent much more time fixing the arrangements around Jev than correcting its choices. The model stayed the same throughout. What changed was the information I gave it, the questions I asked, and how the game used its answers.</p><p>The first lesson was about words. Jev did exactly what my sentences said, which isn’t always what I meant. “When you are safe” sent the cannon into a bomb, because I had meant safe <em>after</em> the move. “Prefer staying put” produced a cannon that stopped chasing aliens, because I hadn’t said which preference came first. Both were fixed by writing the condition precisely and putting the priorities in order. The decision log made that possible. I could read the exact words behind each mistake instead of guessing.</p><p>The second lesson was about time, and it kept coming back. Every answer arrives some while after the question, and the game doesn’t wait. At around 300 ms, the cannon drifted 45 pixels before a “fire” arrived, so good advice landed at the wrong address. On the slower evening, answers took about half a second and seemed to arrive in batches. Jev could effectively see the game only twice a second, and there were moments when every destination on offer was already deadly. The same code, playing the same game, went from losing the cannon every 19 seconds to every 5, largely because the service was slower.</p><p>Response speed turned out to be something I could design around rather than just suffer. The forecasts describe the future rather than the present, simulating the measured delay so each option describes the moment the answer will actually take effect. The code checks a decision before acting on it, dropping a shot if the line of fire has changed since Jev saw it. That alone took shots into our own shields from 29 to one. Overlapping requests, with sequence numbers to throw away stale answers, keep decisions fresher, at least while the service isn’t batching them. The “keep heading there” option gave the cannon a reason to finish its journeys.</p><p>The biggest single improvement was asking before I needed the answer. The planned escape took the cannon from losing a life every 5 seconds to every 76 on that slow evening, because the answer was already waiting when the bomb appeared. If you can’t make the answers arrive sooner, you can still change when you ask the questions.</p><p>The third lesson is less flattering to the premise of the experiment. By the end, Go was doing most of the heavy lifting. It simulated every bomb, predicted where the formation would be, worked out what each shot would hit, and labelled every destination safe, risky or deadly. Once all that is written down, many of Jev’s decisions have fairly obvious answers. Firing is close to a rule: if the laser is ready and an alien will be in the line of fire, shoot. Choosing a destination could be a scoring function that puts safety first, then a target, then distance. The escape could simply take the side with the nearest safe spot. A plain algorithm would make those choices without a network round trip, which, as the slower evening showed, is where most of the trouble came from.</p><p>That doesn’t make the exercise pointless. Space Invaders is a small, fully visible, predictable world, which is exactly where hand-written rules shine. Jev earns its keep when the situation is harder to reduce to numbers, and the interesting part here was learning how to shape the questions and the timing around a model. Whether a few dozen lines of Go could beat Jev at its own game is a story for another day.</p><p>By the end, Jev was competent enough to be fun to watch, though the aliens still got their share of victories.</p><p>The code is at <a href="https://github.com/sausheong/invadersapp">github.com/sausheong/invadersapp</a>, including the build instructions and optional Jev integration. You can play it yourself, or supply a TypeSafe API key and let Jev have a go.</p><h3>Thank yous</h3><p>Thanks to Serge Zaitsev for the original webview package, and the maintainers of <a href="https://github.com/webview/webview_go">webview_go</a> and <a href="https://github.com/gopxl/beep">gopxl/beep</a> for keeping the pieces moving. Thanks also to the <a href="https://docs.typesafe.ai/">TypeSafe</a> team for Jev. The sound effects come from <a href="http://www.classicgaming.cc/classics/space-invaders/sounds">Classics United</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b9b592d5431e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Machines With Wallets]]></title>
            <link>https://medium.com/@sausheong/machines-with-wallets-6c05e99568f8?source=rss-a358058b2410------2</link>
            <guid isPermaLink="false">https://medium.com/p/6c05e99568f8</guid>
            <category><![CDATA[payments]]></category>
            <category><![CDATA[ai-agent]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[ecommerce]]></category>
            <category><![CDATA[singapore]]></category>
            <dc:creator><![CDATA[Sau Sheong]]></dc:creator>
            <pubDate>Sat, 12 Sep 2026 08:23:07 GMT</pubDate>
            <atom:updated>2026-09-12T14:15:58.238Z</atom:updated>
            <content:encoded><![CDATA[<h4>How agents could reshape the movement of money</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IhyVCcNU6ajQlGSFdbuWzw.png" /></figure><p>A family asks its agent to keep the kitchen stocked with essentials, within a weekly budget of $150. When the usual supermarket cannot deliver milk and eggs before the family runs out, the agent finds another shop, but its delivery fee takes the combined spending over budget. The agent postpones a few less urgent items, places both orders and authorises the payments without asking the family to approve them. The family sees the receipts afterwards, having left the agent to decide what to buy now, what can wait and which shop to pay.</p><p>Five friends eat together and one of them pays the bill. Her agent takes the itemised receipt, works out who ordered what, splits the shared dishes and divides the service charge and GST, then sends each friend’s agent the proposed share. Those agents check the claim against what their owners said they ordered, pay without asking again if the amount is within the limit their owner set earlier, and ask their owner to approve it otherwise. No one at the table is a merchant. The agents agree the amounts with one another, using permission their owners gave weeks earlier to settle claims from named friends up to an agreed limit.</p><p>A café runs low on coffee beans and its agent reorders them. If the usual roaster has put prices up, the agent checks the two other suppliers the owner approved and buys from whichever is cheaper. It pays immediately, within the weekly budget the owner authorised beforehand. The owner sees what was bought at the end of the week rather than approving each order.</p><p>A government agency lets an agent assess whether a grant applicant’s documents meet the eligibility criteria, and releases the next instalment where they do, without a caseworker approving every routine case by hand. The agent judges whether the applicant qualifies, and that judgement triggers payment.</p><p>A research agent pays for what it consumes as it works, a few cents to retrieve information from a dataset, a fraction of a cent for another AI to process a request, hundreds of times an hour. There is a service provider, but no retail cart and no human approving each call.</p><p>These five scenes explore what we might entrust to an AI agent, software that acts on our instructions, rather than describe five services already available. Their common challenge is how to authorise payments safely without a person approving each one. Someone still sets the boundaries and remains accountable, but the system must decide whether a particular payment may proceed. That makes the checks before payment, and the means of putting mistakes right afterwards, central to the whole idea. The question is how close existing services and payment systems bring us to these scenes, and what Singapore should do to make them practical.</p><h3>What is being delegated?</h3><p>These examples also help clear up a common confusion between agentic commerce and agentic payment. The terms often appear together because buying something usually ends with paying for it, but they describe different parts of what we delegate to an agent.</p><p><em>Agentic commerce</em> is the shopping journey of finding something, comparing alternatives, agreeing a price and completing a purchase. An assistant can do much of that work without handling payment, perhaps finding the right washing machine and filling the basket before leaving the customer to pay.</p><p><em>Agentic payment</em>, which is what we’re discussing in this article, is whether the system can safely authorise payment without asking a person to approve that transaction. An agent completing checkout after someone clicks approve is useful automation, and is often marketed as agentic payment, but the spending decision still rests with the person. Here, the ambition is to delegate that decision within agreed limits.</p><p>This does not mean giving the model unrestricted access to money. The owner grants permission beforehand, and controls outside the model check each proposed payment against it. The owner must be able to withdraw that permission, while unusual or uncertain cases can still go to a person. The aim is to remove routine approvals without removing oversight or leaving the customer unprotected.</p><p>The grocery, café and research examples involve both agentic commerce and agentic payment. Each agent buys something and pays for it, whether that is milk, coffee beans or access to a dataset. The research agent has no retail basket, but it is still purchasing a service. In all three cases, the owner has delegated some purchasing decisions along with the authority to pay.</p><p>The dinner settlement and grant release involve agentic payments without agentic commerce. The friends have already bought their meal, so their agents are settling what they owe one another. The agency is deciding whether an applicant qualifies for a grant, rather than buying anything from them. That is why a system designed around shopping and checkout can address some of these cases while leaving others largely untouched. To see what each needs, it helps to look at the kind of payment being made.</p><h3>What kind of payment it is</h3><p>Looking at who pays whom makes the differences between the five scenes clearer. The categories can overlap, since a machine buying a service from another machine may also be making a payment between two businesses. Each nevertheless highlights a different requirement for safe delegation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9oWF3qb3Ym_WneBt0K56DQ.png" /></figure><p><strong>Consumer to merchant</strong> payments happen when a person buys from a business, as the family does when it orders groceries. The agent chooses what to buy and pays the shops within the family’s weekly budget. Price, delivery and getting the right goods all matter, along with a way to return an unwanted purchase or question an incorrect charge.</p><p><strong>Person to person</strong> payments move money between individuals, as when the friends settle their shares of dinner. The restaurant has already been paid, and nothing new is being sold. The agents need to agree who owes what and send it to the right person. If someone pays too much, the friends still need a way to resolve the disagreement and return the money.</p><p><strong>Business to business</strong> payments happen between companies, as when the café buys beans from a roaster. They often involve invoices, agreed suppliers and payment terms that allow the buyer to pay later. Businesses already give employees spending limits and require approval for larger purchases, so an agent can work within a familiar set of rules.</p><p><strong>Disbursements</strong> are payments an institution makes to a recipient, such as the agency releasing a grant. Insurance claims, refunds and other payouts also fall into this category. The central question is whether someone is entitled to the money and how much they should receive. Sending money to the correct account does not correct a mistaken decision about who qualifies for it.</p><p><strong>Machine to machine</strong> payments happen when software pays for a service provided by other software, as the research agent does when buying data or computing time. These purchases may cost very little individually but happen hundreds of times an hour. The challenge is to keep payment costs low, control the total spending and check that the service delivered something useful.</p><p>The categories describe the purpose and participants, rather than prescribing how the money moves. Both a family and a café might pay by card or bank transfer, and that choice affects their options if something goes wrong. The payment arrangement must therefore suit the task, including how mistakes will be resolved.</p><h3>What is already working?</h3><p>Agents can already complete purchases and pay bills, but many services still ask a person to approve the payment first. Some go further, acting on an instruction given earlier, such as buying a chosen product when its price falls below a limit. Others have only been demonstrated with selected customers and merchants. The five opening scenes are therefore partly within reach, but we cannot yet assume that an ordinary customer can sign up and let an agent handle them all.</p><p>To understand what a service offers, ask <strong>does the person approve each purchase, or can the agent decide and pay within limits set beforehand?</strong> Then ask who can actually use it. The examples below show why successful payments and growing interest in AI shopping do not, on their own, establish that people are routinely entrusting spending decisions to agents.</p><p><strong>Completing a checkout is not the same as deciding to spend.</strong> An agent may save someone the work of filling in forms and submitting payment after they approve an order. The greater delegation happens when it can act without that final approval, using permission the person gave earlier.</p><p>Amazon offers two forms of delegation. With <a href="https://www.aboutamazon.com/news/retail/amazon-rufus-ai-assistant-personalized-shopping-features">price-triggered buying</a>, eligible Prime members set a target price; the service places a qualifying order using their default payment method and address, then notifies them and allows time to cancel. Requests expire after six months or cancellation. This is bounded advance permission, so it comes closer to the core idea than a checkout requiring confirmation each time. With <a href="https://www.aboutamazon.com/news/retail/amazon-shop-direct-external-stores">Buy for Me</a>, customers confirm the order before an agent completes checkout on another brand’s site, through a US offering for eligible products.</p><p><a href="https://about.ads.microsoft.com/en/solutions/technology/agentic-commerce">Copilot Checkout</a> and <a href="https://www.perplexity.ai/help-center/en/articles/10352906-what-is-instant-buy">Perplexity Instant Buy</a> retain customer confirmation, making them examples of assisted checkout rather than the unattended authorisation considered here, with Perplexity limited to US users outside its enterprise plans. What these services allow customers to do can change quickly. On 24 March 2026, OpenAI said Instant Checkout had lacked flexibility and <a href="https://openai.com/index/powering-product-discovery-in-chatgpt/">shifted towards product discovery</a> and merchants’ own checkout. <a href="https://help.shopify.com/en/manual/online-sales-channels/agentic-storefronts">Shopify’s documentation</a> accordingly separates ChatGPT referrals from direct checkout in supported channels such as Google and Copilot.</p><p><a href="https://support.ramp.com/pay-bill-pay-invoices-via-ramp-card/">Ramp’s operational bill-payment feature</a> creates a digital card with spending restrictions and uses it to pay a supplier through its website after the business has approved the bill. It covers eligible QuickBooks-generated, card-accepting invoices up to $100,000, but does not automatically pay part of an invoice. Because the bill has already been approved, this demonstrates automated execution rather than an agent independently deciding that a new payment is permitted.</p><p><strong>A successful trial does not mean everyone can use the service.</strong> Even when real money moves, access may be restricted to selected users, merchants or payment providers. Ramp’s separate <a href="https://agents.ramp.com/docs/guides/agentic-payments">platform for standalone agents</a> was available to a limited group of early users, with additional payment methods being tested privately. That is a different level of availability from a service an ordinary business can sign up to use.</p><p>Visa reported <a href="https://usa.visa.com/about-visa/newsroom/press-releases.releaseId.21961.html">hundreds of controlled real transactions</a> by December 2025, covering consumer purchases and business-to-business bill payments. Real money moved, but the transactions took place in trials with selected participants. That is a useful milestone on the way to a service, while leaving open how widely it can be used and how well it copes with repeated use and mistakes.</p><p>Those trials also show why access depends on more than the payment network. Visa’s <a href="https://usa.visa.com/about-visa/newsroom/press-releases.releaseId.21961.html">pilot update</a> included Skyfire connecting Consumer Reports recommendations to purchasing, and PayOS helping BeyondStyle buy from Jomashop. The assistant need not belong to the shop, which makes the relationship between the recommender, the merchant and the payment provider part of the product design.</p><p><a href="https://blog.cloudflare.com/monetization-gateway/">Cloudflare’s Monetization Gateway announcement</a> pointed to early access and <a href="https://aws.amazon.com/blogs/machine-learning/agents-that-transact-introducing-amazon-bedrock-agentcore-payments-built-with-coinbase-and-stripe/">AWS’s AgentCore payments announcement</a> to a preview, reinforcing the need to check which tasks each service can actually perform and who can use it.</p><p><strong>More AI shopping does not necessarily mean more payments decided by agents.</strong> Providers are building payment connections and customers are using AI to find products, but those activities do not tell us how often an agent buys something without asking for approval.</p><p>Adobe recorded a <a href="https://experienceleague.adobe.com/en/on-demand-events/ai-driven-growth">4,700 per cent rise in AI-referred US retail visits</a> between July 2024 and July 2025, from a very small starting point. Its separate <a href="https://business.adobe.com/uk/blog/the-explosive-rise-of-generative-ai-referral-traffic">February 2025 survey</a> found 39 per cent using AI for online shopping. Adyen’s <a href="https://www.adyen.com/press-and-media/retail-report-2026-us">US retail report</a> put assistant usage at 35 per cent, up from 12 per cent a year earlier. These figures show more people using AI to find products, rather than agents making purchases independently.</p><p>The distinction becomes clearer in <a href="https://www.channelengine.com/en/blog/state-of-marketplace-shopping-channelengine-report">ChannelEngine’s five-country survey</a>. Some 58 per cent had researched products with AI, but only 17 per cent felt comfortable completing a purchase through it. That last figure measures confidence, not completed transactions. Finding a product, buying inside a chat window and letting software decide and pay unattended remain different behaviours.</p><p>The practical starting point is a service for a specific task, with clear spending limits and participating sellers and payment providers. Progress towards the five opening scenes means making delegated spending available through services that work repeatedly, enforce the customer’s limits and handle mistakes. To see what that requires, we need to follow how permission becomes an order, a payment and a record that can be checked afterwards.</p><h3>How does the payment stack fit together?</h3><p>We already authorise some payments in advance, allowing them to happen without asking us again. Direct debits, standing orders and recurring card charges are familiar examples. An agent extends the arrangement by interpreting a goal, perhaps choosing a supplier or accepting a substitute the person never considered. The challenge is to preserve the safety of limited advance permission when the exact payment is not known at the outset.</p><p>For purchases, it helps to follow the transaction through four stages. Someone gives the agent permission, the agent agrees a purchase, the payment is checked and executed, and the parties keep records and resolve any problems. For a dinner settlement or grant, checking a debt or entitlement takes the place of agreeing a purchase. Permission, payment and recovery still have to work.</p><p>Each stage involves information passing between systems. The grocery agent needs the shop to understand its order, while the payment provider needs to check the amount and the authority to pay. Those systems need an agreed way to express and exchange that information. This is what a <em>protocol</em> provides, so the participants can interpret a request and know how to respond.</p><p>Different protocols cover different parts of the transaction. Some deal with orders, others with evidence of permission or requests for payment. Network programmes and payment services connect those exchanges to the businesses and infrastructure that process the purchase. The diagram shows how their roles overlap across the four stages.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xTdT6Rttm0yBDroQ7tN8EQ.png" /></figure><p>The bars show the roles each protocol or programme can support, rather than a sequence of technologies every payment must use. A bar reaching into payment execution does not mean that the protocol itself settles funds, while a bar reaching into resolution does not promise reimbursement. The lighter extensions distinguish evidence that could help investigate a dispute from a service that handles the dispute. Actual capabilities depend on the participating providers and their implementation.</p><p><strong>Give permission.</strong> Before the grocery agent spends anything, the family sets its weekly budget, approved retailers and rules for substitutions. That authority needs to be recorded in a form the service can check and the family can withdraw. AP2 provides mandates, verifiable records of permission, while payment providers can issue restricted credentials such as tokens or limited spending keys. A credential is evidence a system can check to establish identity or permitted access. Recording permission and enforcing it are different jobs, so the service must still reject a proposed payment that exceeds the limits.</p><p><strong>Agree the purchase.</strong> The agent and seller need to establish what is being supplied and what it costs. ACP and UCP give shopping agents structured ways to work with product information, baskets and checkout. A research agent buying data may need a simpler exchange, with x402 or MPP allowing the service to state its price and payment terms. Whether it is groceries or data, the final proposal must be checked against the owner’s instructions. A technically valid order may still be the wrong purchase.</p><p><strong>Execute payment.</strong> The service checks the proposed payment against active permission and submits it through a supported payment provider. AP2 can supply evidence of authority, while restricted tokens and spending keys can constrain its use. ACP and UCP connect checkout to payment processing, and x402 and MPP support payment exchanges for software services. MPP also supports spending sessions, allowing continuing use within an agreed arrangement. Underneath these connections, card, bank-transfer or stablecoin infrastructure moves the funds. The agent must have an authorised way to use that infrastructure; supporting a protocol does not by itself provide access to a bank account or payment network.</p><p><strong>Record and resolve.</strong> The parties need to retain what was requested, what was permitted, what was paid and what was delivered. Records must be collected throughout the transaction, even though the diagram places their later use at the end. UCP includes after-sales operations, while Amex ACE supplies intent and basket context that can help with authorisation and disputes. AP2 and other evidence mechanisms can help establish what happened without deciding who bears the loss. If the agent invents a delivery confirmation or buys something outside the customer’s instructions, someone still has to investigate, explain the outcome and arrange whatever remedy applies.</p><p>Across these stages, three checks answer different questions. <strong>Authentication</strong> establishes who sent an instruction or controls the credential being used. A digital signature helps show that a message came from the holder of a particular key and has not been altered, but does not establish that the holder was entitled to make the purchase. <strong>Authorisation</strong> checks whether this payment is permitted, including who entrusted the key to the agent, the limits imposed and whether permission is still active. <strong>Fraud checks</strong> look for deception or suspicious activity even when the identity and permission appear valid.</p><p>For the family’s second grocery order, authentication helps establish that the request came from its recognised agent. Authorisation checks the chosen retailer, goods and combined spending against the family’s instructions. Fraud checks consider whether the shop is fraudulent or its payment details have been substituted. These checks do not correspond one to one with the four stages. The merchant may authenticate the agent when it connects, the agent service may enforce spending limits before requesting a credential, and the payment provider may apply further checks before processing the charge.</p><p>Visa TAP, Mastercard Agent Pay, Amex ACE and Ant AMP help connect some of these functions through different networks and services, whose roles become clearer once we examine the core protocols. A framework such as SAFR or a similar framework can guide an institution’s checks on the proposed action without removing its responsibility for the service. The aim is to connect advance permission to reliable execution and a practical way to recover when something goes wrong, so the customer can supervise the arrangement without approving every payment. For the grocery agent, the first practical connection is to the shop, where its choices must become an order the merchant can fulfil. That is where ACP comes in.</p><h3>ACP</h3><p>OpenAI and Stripe’s <a href="https://www.agenticcommerce.dev/docs/concepts/architecture"><strong>Agentic Commerce Protocol</strong></a> gives an agent a structured way to talk to a merchant instead of trying to work out a checkout page designed for people. The merchant still owns the order and remains the merchant of record, the business responsible for the sale to the customer. A payment provider supplies a restricted credential, such as a token usable only with a particular merchant, up to a set amount and before an expiry time. That lets the agent complete the purchase without being given reusable card details.</p><p>ACP’s <a href="https://github.com/agentic-commerce-protocol/agentic-commerce-protocol/blob/main/changelog/2026-04-17.md">April 2026 release</a> covers baskets, product feeds and orders, as well as delegated customer authentication. A merchant can list what its system supports at a standard web address, /.well-known/acp.json, and agents can also interact through MCP, a standard for connecting them to software tools. The release requires POST idempotency, a rule for requests that create or change something, so retrying the same request should not accidentally create a second operation, and includes 3-D Secure flows for additional cardholder authentication. The <a href="https://github.com/agentic-commerce-protocol/agentic-commerce-protocol">repository labels ACP beta</a>, so the parties need to agree which version they implement rather than assume every ACP connection behaves identically.</p><p>The checkout has several participants with different responsibilities. The agent represents the buyer, the merchant manages the order, and the payment provider supplies and processes the credential. Structured product feeds let the merchant supply product descriptions directly to the agent, while checkout operations keep the basket contents and price consistent. The merchant can decide whether to accept a particular agent. Existing fraud, return and dispute arrangements still matter because a protocol connection does not itself transfer those responsibilities to the assistant.</p><p>ACP therefore helps an agent execute an order using restricted payment access, but cannot by itself justify removing human approval. A scammer could manipulate a product description or checkout response so the agent requests a valid credential for the wrong purchase. The surrounding service must check the merchant, final amount and permitted task before releasing that credential; a restricted token limits where and how much the agent can spend, but does not prove that the purchase is legitimate.</p><h3>UCP</h3><p>The merchant connection also needs to cover what happens around checkout, from finding a product to returning it. Google’s <strong>Universal Commerce Protocol</strong>, or UCP, allows participating businesses to make those shopping and after-sales functions available to agents. Returns, tracking and loyalty matter because an agent’s work should not end at a successful charge. Google offers shopping through AI Mode and Gemini, but each merchant’s participation and supported functions determine what an agent can actually do.</p><p>Google <a href="https://blog.google/products/ads-commerce/agentic-commerce-ai-tools-protocol-retailers-platforms/">introduced Universal Commerce Protocol</a> on 11 January 2026 with partners including Shopify. A merchant lists the operations it supports at the standard address /.well-known/ucp, so an agent can discover those operations automatically. UCP&#39;s <a href="https://ucp.dev/specification/overview/">payment architecture</a> also separates the way someone pays from the software that obtains the payment credential. The agent&#39;s platform receives a token it can pass on without needing to inspect the underlying payment details, and the merchant processes it through its provider.</p><p>To carry evidence of permission, a UCP integration can add the <strong>Agent Payments Protocol</strong>, or AP2, as an <a href="https://ucp.dev/specification/payment/extensions/ap2-mandates/">optional UCP extension</a>. It does not get that capability merely by supporting UCP, nor does UCP automatically permit unattended purchases. Both ACP and UCP help the systems form an order and arrange payment; the question of whether the agent chose what the customer actually wanted still needs attention.</p><p>Shopping through an assistant also requires merchants to supply product information the software can use. <a href="https://docs.paypal.ai/growth/agentic-commerce/overview">PayPal’s Agent Ready and Store Sync services</a> separate payment acceptance from making catalogues available to agents, while its <a href="https://developer.paypal.com/agent-ready/overview/">developer documentation</a> describes ACP and UCP integration paths. An existing network of merchants and customers could help a service expand, but participants still need approval and the required connections to use it.</p><p>UCP supplies a common shopping interface, rather than a general licence for an agent to spend. Its contribution to unattended payment depends on the authorisation and fraud controls attached to the checkout. Discovering that a merchant supports a protocol establishes technical compatibility, not that the merchant is trustworthy or that the customer agreed to buy from it.</p><h3>AP2</h3><p>That unanswered question of permission is the focus of the <strong>Agent Payments Protocol</strong>, or AP2. Its central idea is a mandate, like a permission slip whose origin and contents other systems can verify. It records what an agent has been authorised to do. Following the September 2025 launch, the <a href="https://github.com/google-agentic-commerce/AP2/blob/main/CHANGELOG.md">v0.2.0 changelog</a> of 28 April 2026 revised the original Intent, Cart and Payment mandate model.</p><p>The revised design separates a <a href="https://ap2-protocol.org/ap2/checkout_mandate/">Checkout Mandate</a>, describing what may be bought, from a <a href="https://ap2-protocol.org/ap2/payment_mandate/">Payment Mandate</a>, describing the funding authority. Both have open and closed forms. The open form describes the limits before the final purchase is known; the closed form connects that authority to the particular checkout or payment. In direct mode, the person approves the particular purchase. In autonomous mode, the person <a href="https://ap2-protocol.org/ap2/agent_authorization/">authorises constraints and an agent key</a> so the agent can produce the transaction-specific authorisation later. The key identifies the agent allowed to act; it does not let the agent invent wider permission.</p><p>A merchant need not receive every private preference to check the relevant restrictions; selective disclosure means sharing only the parts of the record needed for that check. But a system cannot safely ignore a condition it does not understand. “Buy trail running shoes under $150 that arrive by Friday” still leaves room for disagreement about fit, quality and acceptable sellers. The signed record helps everyone examine what happened, without proving that the agent made a sensible choice.</p><p><a href="https://ap2-protocol.org/ap2/specification/">Version 0.2</a> leaves detailed dispute procedures and agent-to-agent mandate delegation outside its scope. The friends’ agents cannot therefore assume that exchanging AP2 messages settles who may authorise whose payment. Someone also needs to keep track of active mandates, enforce expiry, protect signing keys and notify customers; those remain <a href="https://ap2-protocol.org/ap2/implementation_considerations/">implementation responsibilities</a> alongside the merchant and payment connections.</p><p>The evidence is useful precisely because the participants have different jobs. A merchant needs to know what it may fulfil, while a payment provider needs the funding authority; neither necessarily needs every detail of the customer’s conversation. AP2 itself does not settle the money, and combining it with another payment mechanism still requires an agreed implementation. There is also a human weakness to consider. If every ambiguous instruction produces an escalation, reviewers can become so overloaded that approval turns into a reflex. Good delegation needs manageable exceptions as well as signed records.</p><p>AP2 is more directly concerned with replacing per-payment approval through verifiable advance permission. Even then, technical evidence and legal responsibility are separate questions. If the agent signs an order that fits the amount limit but misreads the instruction, the mandate helps establish what was permitted and what happened; it does not decide whether the customer, agent provider, merchant or payment provider bears the loss. The service terms and applicable law still matter, and the customer needs a practical route to challenge the charge.</p><p>An agent can also be wrong without anyone attacking it. It might invent a delivery promise, assume the family authorised a substitution or claim an invoice has been verified when it has not. These are hallucinations, plausible statements unsupported by the actual records. Signing the resulting payment does not make those statements true. The authorisation check needs evidence from the order, customer instructions and supplier records, and should stop when the required evidence is missing.</p><h3>x402</h3><p>Once permission can be checked, the service still needs a way to request and collect payment. For an agent buying data or computing time, that need not involve a full shopping checkout. It could ask for a resource, be told the price, pay and receive the result. Coinbase’s <strong>x402</strong> builds that exchange around HTTP, the rules web clients and servers use to communicate. Its 402 status means Payment Required, giving software a standard way to say that access costs money. In July 2026, the Linux Foundation announced the <a href="https://www.linuxfoundation.org/press/linux-foundation-announces-operational-launch-of-x402-foundation-to-standardize-internet-native-payments-for-ai-agents-and-applications">operational launch of the x402 Foundation</a> and completed protocol contribution, with 40 members.</p><p>The exchange begins when an agent requests something that costs money. The service replies with <a href="https://docs.x402.org/core-concepts/http-402">402 Payment Required</a> and its payment terms; the agent then signs an authorisation and tries again. Once the payment has been checked and handled under the agreed settlement rules, the service returns the resource and a payment response. A <a href="https://docs.x402.org/core-concepts/facilitator">facilitator</a> can check the payment and arrange the transfer of funds for the seller, although a seller can also perform those functions itself.</p><p><a href="https://x402.org/x402-v2-launch/">Version 2</a> broadened the supported networks and payment schemes, and added ways to discover services and handle identity. Payments can settle immediately or in batches. The protocol does not require a separate blockchain transfer for every request, nor is it limited to USDC, a dollar-linked stablecoin, on the Base blockchain. In practice, the buyer and seller still need to support the same combination of token, network and payment scheme.</p><p>Underneath the simple request-and-retry exchange, the signing mechanism depends on the network. With tokens supporting the <a href="https://docs.cdp.coinbase.com/x402/support/faq">EIP-3009 transfer-authorisation standard</a>, the buyer can sign a transfer authorisation and let another party submit it and cover the network fee. The Solana blockchain instead supports separating the transaction signer from its fee payer. The practical benefit is similar, since a buyer need not keep a second currency solely to pay transaction fees, but the verifier still has to check the actual instructions it will submit.</p><p>The cost of processing each payment also matters. Coinbase’s <a href="https://docs.cdp.coinbase.com/x402/support/faq">facilitator pricing</a> includes 1,000 free transactions a month followed by $0.001 per transaction, while running another facilitator is an option. A tenth of a cent sounds negligible until the service being sold costs less than that. Payment batching, sessions and the choice of settlement scheme can matter more than the headline fee.</p><p>Removing repeated human approval also removes an opportunity to notice a bad request. <a href="https://arxiv.org/abs/2605.11781">Security research on x402</a> examines attacks against payment flows, while the project’s <a href="https://github.com/x402-foundation/x402/security/advisories/GHSA-qr2g-p6q7-w82m">March 2026 SDK advisory</a> shows why payment operators need to keep the software libraries they depend on up to date. Requests reused to obtain another payment, excessive charges and instructions that trick an agent into spending need checks outside the model as well as correct cryptography.</p><p>For unattended payment, x402 supplies the request-and-pay mechanism. The operator still needs a separate decision about whether this resource, recipient and price are allowed. A malicious service could present a plausible payment request or insert instructions into returned content that steer the agent towards further purchases. The application should treat those instructions as untrusted data, enforce a task-wide budget and stop suspect spending even when every payment signature is valid.</p><h3>MPP</h3><p>The task-wide budget becomes especially important when the research agent keeps buying data as it works. It could agree a spending allowance with the service and pay for accumulated usage, instead of settling each tiny request separately. That is one of the patterns supported by Tempo and Stripe’s <a href="https://stripe.com/blog/machine-payments-protocol"><strong>Machine Payments Protocol</strong></a>, introduced on 18 March 2026. MPP supports these purchases through conventional payment infrastructure and stablecoins. In <a href="https://docs.stripe.com/payments/machine/mpp">Stripe’s integration</a>, the service first asks for payment, and the agent repeats its request with a payment credential attached. It records the payment and returns a receipt, using either Shared Payment Tokens, restricted credentials for a purchase, or addresses into which stablecoins are deposited. These software interfaces include preview versions, and each payment method has its own conditions, so developers need to check availability for the integration they choose.</p><p>MPP’s SDK, the software library developers use to implement it, added support for <a href="https://mpp.dev/">x402 exact flows, which pay a specified amount</a> in June 2026. That makes some integrations easier without turning the two protocols into the same thing. Neither can tell whether the data was useful. Nor can a per-call spending cap protect an overall budget when several agents buy at once, so the application needs to set aside money for each pending purchase, match the payment to what was received and stop spending when further purchases no longer help complete the task.</p><p>Tempo’s <a href="https://rustdocs.tempo.xyz/tempo_precompiles/account_keychain/index.html">access-key mechanism</a> lets an account authorise a secondary key with per-token spending caps and an expiry. The agent can hold that limited authority instead of the main account key. This is one way to enforce a budget outside the agent, although it still cannot decide whether a purchase serves the owner’s purpose.</p><p>Within the spending allowance described earlier, MPP’s sessions track what the buyer owes as it uses a service. The buyer sends cumulative payment vouchers, signed records of the total owed so far, allowing charges to accumulate without settling every request separately. The <a href="https://mpp.dev/blog/sessions-improved">session design</a> has a specification submitted to the Internet Engineering Task Force, or IETF, describing the payment channel and voucher model. An Internet-Draft is work towards a standard, not evidence that the IETF has adopted a finished standard. Sessions are now a formal MPP intent, meaning a standard type of payment operation. The design allows implementations beyond Tempo rather than permanently tying sessions to that blockchain.</p><p><a href="https://mpp.dev/blog/subscriptions">Subscriptions</a> add another pattern, beginning with Tempo stablecoins and an access key authorised for a particular subscription. The service can recognise an already-paid period rather than demand another payment for every visit. Together, one-off charges, sessions and subscriptions cover different ways of buying a continuing service. Their availability and cancellation behaviour depend on the payment method and integration. The operator also needs to decide who holds the digital funds and keys, which network processes the payments and which providers the service depends on.</p><p>MPP brings continuing spending closer to the model of advance authorisation, but an allowance can also become a scammer’s target. A service might repeatedly charge for worthless responses without breaching a per-request cap. The operator needs limits on total use, checks on delivery and an effective way to terminate the session. A payment receipt records the transaction, but does not establish that the service delivered useful results or that the buyer is entitled to reimbursement.</p><p>With those mechanisms and their limits in view, we can return to how much they are actually being used. <a href="https://www.visa.com/en-us/thought-leadership/innovation/agentic-payments-from-the-ground-up">Visa and Artemis reported </a>about $15 million across 109.6 million x402 transactions after filtering the activity and $25,000 across 115,000 early MPP transactions. Published in July, the figures cover activity through 21 April 2026 and exclude transactions identified as testing or wash activity, where money moves without representing ordinary independent demand.</p><p>A separate <a href="https://arxiv.org/abs/2607.12575">July preprint</a> examined 136.7 million payments settled on the Base blockchain and found substantial activity that was fictitious or moved within connected groups. The studies cover different things, so their totals cannot be combined into one market estimate. Their more useful lesson is that a busy payment network does not necessarily mean many customers are buying useful services.</p><h3>Who will accept an agent?</h3><p>These protocols describe ways to exchange orders, permission and payment, but a working service also needs businesses willing to rely on those exchanges and answer for failures. The customer is only one party who has to agree to an agent purchase. A merchant must be willing and able to accept it, and the payment provider must support the arrangement. An agent navigating an ordinary website can encounter changing page layouts and anti-bot controls, while a direct software connection lets the merchant make the terms of access explicit.</p><p>A customer may want to delegate a purchase while the merchant refuses the agent access. <a href="https://www.aboutamazon.com/news/company-news/amazon-perplexity-comet-statement">Amazon’s dispute with Perplexity</a> makes that conflict explicit. Amazon objects to how Comet accesses its store and describes concerns about transparency and the customer experience, even while developing its own shopping assistants.</p><p>The commercial tension is easy to understand. If another company’s agent chooses the products and handles the interaction, the retailer can lose control of recommendations, advertising and the ongoing customer relationship. The payment might be perfectly authorised by the buyer and still arrive through a channel the merchant does not accept. Signed mandates cannot settle that disagreement. A working agent service needs permission from the businesses it uses as well as from the person whose money it spends.</p><p><a href="https://www.aboutamazon.com/news/retail/amazon-shop-direct-external-stores">Amazon’s Buy for Me</a> demonstrates cross-site execution after customer confirmation, while <a href="https://help.shopify.com/en/manual/online-sales-channels/agentic-storefronts">Shopify’s channel-specific checkout rules</a> show that catalogue visibility and payment access are separate decisions. These examples show that merchants must agree to accept agent purchases and connect their systems to support them. Card networks are working on those connections through their existing business relationships and payment infrastructure.</p><h3>Visa and Mastercard</h3><p><a href="https://developer.visa.com/capabilities/trusted-agent-protocol/overview">Visa’s <strong>Trusted Agent Protocol</strong></a> helps a merchant establish whether a visitor is a recognised purchasing agent or an unwanted bot. It uses <a href="https://developer.visa.com/capabilities/trusted-agent-protocol/trusted-agent-protocol-specifications">HTTP Message Signatures</a> to protect the information accompanying a request and connect it to an agent and transaction context. The merchant checks trusted keys, whether the message has been altered and whether an old request is being reused. The bank that issued the customer’s card still authorises the payment, and settlement follows the existing arrangements. Some integration details are available only after onboarding into Visa’s programme.</p><p>Recognising the customer behind an agent also affects the merchant’s business and the customer’s privacy. <a href="https://developer.visa.com/use-cases/trusted-agent-protocol">Visa’s messages</a> can carry agent intent and consented customer-recognition information, helping a shop distinguish browsing from buying and reconnect a returning customer with an existing account or loyalty relationship. That is valuable to a retailer that would otherwise see only an agent, but it also means personal identifiers can travel when the customer is absent. Implementers need to decide which information is necessary and what the customer has agreed to share.</p><p>Visa’s <a href="https://investor.visa.com/news/news-details/2026/Visa-Opens-the-Door-to-AI-Driven-Shopping-for-Businesses-Worldwide/"><strong>Intelligent Commerce Connect</strong></a>, announced in April 2026, aims to connect networks, protocols and the systems holding payment credentials through a common integration. It was introduced as a pilot, so the ambition is to reduce the number of separate connections businesses need, rather than establish that every combination already works.</p><p>Mastercard’s <a href="https://www.mastercard.com/us/en/news-and-trends/press/2025/april/mastercard-unveils-agent-pay-pioneering-agentic-payments-technology-to-power-commerce-in-the-age-of-ai.html"><strong>Agent Pay</strong></a>, introduced in April 2025, builds on tokenisation, which replaces reusable payment details with a digital credential. Registered agents use these credentials, called Agentic Tokens, to connect their purchases to the authorised payment arrangement. Its separate <a href="https://www.mastercard.com/us/en/news-and-trends/stories/2026/verifiable-intent.html"><strong>Verifiable Intent initiative</strong></a>, announced with Google in March 2026, connects who the customer is, what they authorised and what the agent did through signed records that reveal only the information a verifier needs. Its <a href="https://verifiableintent.dev/">Draft v0.1</a> specification describes how participating systems can record that evidence. It is a separate specification, so supporting Agent Pay does not automatically mean supporting every part of Verifiable Intent.</p><p>Mastercard also moved into high-frequency resource purchases with <a href="https://www.mastercard.com/us/en/news-and-trends/press/2026/june/mastercard-launches-agent-pay-for-machines.html"><strong>Agent Pay for Machines</strong></a> in June 2026, describing organisations setting payment permissions, checking participants and moving funds through cards, accounts and stablecoins. Partners were validating priority use cases, so the announcement establishes the programme’s direction without supplying evidence of widespread machine-payment volume. Across these initiatives, actual access depends on issuer, merchant, provider and agent enrolment, rather than the total number of merchants accepting the network’s cards.</p><p>These programmes can help identify agents and connect purchases to customer permission, but recognition alone does not settle liability. Before routine human approval disappears, the parties need clear terms for an agent exceeding its authority, a provider failing to enforce a limit, or a merchant supplying misleading information. Customers should know whom to contact and what evidence is needed, rather than being sent between the bank and the software provider. Existing <a href="https://www.abs.org.sg/consumer-banking/consumers/credit-card-chargeback-dispute-resolution">card dispute processes</a> provide routes for particular claims, subject to their conditions; a valid agent credential is neither a blanket guarantee of reimbursement nor an answer to every dispute.</p><p>A dispute can arise even when nobody stole credentials and the payment stayed within budget. The customer may say the agent bought something they never permitted, while the merchant says it delivered exactly what was ordered. Resolving that disagreement requires the original instruction, the permission in force, the final order, the checks performed and the delivery record. A payment receipt alone cannot show whether the agent misunderstood its task, the merchant misrepresented the goods or the payment provider failed to enforce a restriction.</p><h3>American Express</h3><p>American Express approaches that dispute problem by connecting the customer’s instructions to the final purchase. Its <a href="https://www.americanexpress.com/en-us/newsroom/articles/innovation/american-express-debuts-agentic-commerce-experiences--ace--devel.html"><strong>Agentic Commerce Experiences</strong> developer kit, or ACE</a>, announced in April 2026, supports that effort. Its five services cover verifying agents, linking a customer’s card, recording purchase intent, issuing tokenised payment credentials and supplying basket details for authorisation and disputes. Account enablement, intent intelligence and payment credentials had published specifications at launch; agent registration and cart context remained under development. Amex’s model combines roles in the customer and merchant relationship, giving it visibility across both sides of a purchase.</p><p>The accompanying <a href="https://www.americanexpress.com/en-us/company/agentic-commerce/">Amex Agent Purchase Protection</a> addresses what happens when an agent buys something outside the customer’s authenticated instructions. The proposed protection covers eligible agent-error charges on specified US-issued Amex credit cards, with a registered, ACE-integrated agent passing that intent to Amex. Customers must first attempt a merchant return where possible, and claims remain subject to review. Subjective instructions such as buying the “best” item may not qualify. This gives the evidence collected by payment protocols a practical purpose in resolving mistakes, although the protection is described as forthcoming and does not establish availability for Singapore-issued cards.</p><p>This also shows the limits of treating every hallucination as a protected purchase error. If the agent invents a product feature but the merchant fulfils the order correctly, the complaint may concern the agent service rather than merchant fulfilment. Any return, card dispute or agent-purchase protection depends on its terms and the evidence. A promise to cover an agent deviating from authenticated instructions should not be read as a promise to reimburse every disappointing purchase.</p><h3>Wallets and payment providers</h3><p>The same need to connect identity, permission and recourse extends beyond cards. Mobile wallets provide another route through established customer and merchant relationships. Ant International, which provides payment services across markets, announced its <a href="https://www.prnewswire.com/apac/news-releases/ant-international-launches-open-sourced-agentic-mobile-protocol-to-drive-ai-commerce-302755681.html"><strong>Agentic Mobile Protocol</strong></a> in April 2026 for wallets, banking apps, super apps and wearable interfaces, with Alipay+ partners working on implementation. The announcement describes AMP as open-sourced but leaves its precise cryptographic guarantees unclear, making a direct comparison with AP2 difficult.</p><p><a href="https://www.antom.com/news/ant-internationals-antom-debuts-agentic-payment-solution-pioneering-apm-checkout-solution-and-trusted-ai-for-secure-transactions">Antom’s September 2025 Singapore announcement</a> describes how Ant International’s merchant payment business approaches these transactions. It covers cards and other payment methods, software connections through MCP, purchases the customer confirms and permission given in advance subject to conditions, alongside card-network pilots. Those proposed flows leave Singapore consumers wondering which wallets and merchants actually support them. The network could make the service available to many customers, but its size does not show how many can actually delegate a payment.</p><p>Payment companies are investing heavily in infrastructure while measured agent spending remains small. Mastercard <a href="https://www.mastercard.com/nz/en/news-and-trends/press/2026/march/Mastercard-to-acquire-BVNK-to-connect-on-chain-payments-and-fiat-rails.html">agreed to acquire BVNK for up to $1.8 billion</a>, while Stripe <a href="https://stripe.com/newsroom/news/stripe-completes-bridge-acquisition">completed its Bridge acquisition</a> and reported <a href="https://stripe.com/annual-updates/2025">$1.9 trillion in total business volume for 2025</a>. These investments create more ways to connect conventional money and stablecoins. They do not tell us how much an agent has actually bought, just as total stablecoin transfers include much more than payments for goods or services.</p><h3>How is China approaching it?</h3><p>Beyond investment in payment infrastructure, China shows what can happen when large platforms already combine customers, merchants and everyday services. Card networks exist there too, but Alipay and WeChat already combine payment access with everyday services and customer relationships. They can add agent functions to services their customers and merchants already use, instead of first having to recruit merchants to a new system.</p><p>Alipay’s Ah Bao brings that model into a conversational interface. Its <a href="https://www.haipay.net/news/alipay-ah-bao-ai-agent-interface">initial service offering</a> covered more than 10,000 adapted services, including household bills, pet services and EV charging, through an invitation-based rollout. The <a href="https://paypedia.org/en/actualites/2026-08-17-alipay-commerce-agentique-aha">August platform expansion</a> described connections to five smartphone brands representing more than 70 per cent of the Chinese market and 16 carmakers. Those figures describe potential distribution, rather than a count of autonomous purchases. Coffee and food ordering sit alongside services, so the ambition reaches well beyond a retail checkout.</p><p>A <a href="https://ffnews.com/news/stepfun-and-alipay-partner-to-revolutionize-ai-agent-integration-for-everyday-tasks">StepFun demonstration</a> made the interconnection idea tangible by combining a request for a nearby EV charger with a coffee delivery through Alipay’s services. The result was an order ready for confirmation, which demonstrates coordination without proving unattended payment.</p><p>Behind those consumer interfaces are mechanisms for connecting and checking agents. <a href="https://aipay.alipay.com/act/apass"><strong>APASS</strong></a> addresses agent identity, continuing verification, intent and evidence, including who is responsible for the agent. AHA, or Agent Hub Access, connects services and agents across participating systems. Alipay’s <a href="https://aipay.alipay.com/docs/overview.html">AI payment products</a> then distinguish Vibe Pay for applications, Skill Pay for software tasks an agent can call, Machine Pay for software services charged by usage, and continuing subscriptions. An AI wallet is intended to let customers see and control what their agents spend, although the announced wallet capabilities should not all be assumed to be generally available. Connecting the layers would let an assistant reach another provider’s service without each handset maker rebuilding every payment integration.</p><p>Tencent starts from its own agent interfaces. Its <a href="https://www.caixinglobal.com/2026-06-18/tech-brief-june-18-tencent-lets-ai-agent-make-purchases-through-wechat-pay-102455568.html">WorkBuddy payment integration</a> uses a dedicated WeChat Pay AI card for purchases such as Meituan deals, with the customer confirming on their phone before funds move. QClaw also formed part of the expansion. This is useful assistance with payment execution, but the customer still makes the final approval. It therefore does not yet demonstrate the unattended authorisation at the centre of these five scenarios. The platform still controls which services an agent can reach, so permission from the customer alone does not open every app to automation.</p><p><a href="http://jd.com/">JD.com</a> added another approach with its <a href="https://finance.eastmoney.com/a/202606113768507410.html">A2P2 announcement on 11 June 2026</a>, presenting an Agent Autonomous Payment Protocol intended to make delegated spending bounded and traceable. An announced protocol does not by itself establish adoption across rival platforms. Du Xiaoman’s <a href="https://clawpay.dxmjuhe.com/">DXMClawPay</a> supplies another route for agent and skill developers, advertising integration with WeChat Pay, Alipay and its own payment service. This is a way to connect paid services to agents, rather than evidence that every resulting purchase happens without human approval.</p><p>The broader picture is several competing systems with large potential audiences, rather than one Chinese standard that every agent can use. For Singapore, the lesson is that companies can make services available and connect merchants while common standards are still being developed. Making different providers’ systems work together remains a separate task.</p><h3>What are national rails doing?</h3><p>Connecting providers also brings us to the systems underneath their services. National payment systems, often called payment rails, move money between accounts. They offer another route to delegation, alongside the card and wallet programmes. Their relevance is whether they can recognise limited permission in advance, check each payment and stop it when permission is withdrawn, without sending every decision back to the payer. An April 2026 IMF note described the shift from “click to pay”, where a person initiates payment, to “decide to pay”, where delegated software anticipates a need, weighs options and executes. Several systems already contain the necessary mandate mechanisms, with varying degrees of adaptation for agents.</p><h3>Brazil</h3><p>Brazil illustrates why an agent service may still choose a different route even when domestic rails support recurring payments. Its instant-payment system, Pix, added recurring collections through Pix Automático in 2025, and Banco Central continues extending Pix, yet Brazil’s reported first AI agent payment used Visa Intelligent Commerce when Banco do Brasil completed it in March 2026. Even where instant payments are widely used, a provider may choose cards because the card programme already supports recognising agents.</p><h3>United Kingdom</h3><p>The UK offers a closer look at how permission can be built into account payments before agents enter the picture. With a Variable Recurring Payment, or VRP, a customer agrees that a provider may take repeated payments within specified limits. The customer can withdraw that permission in the banking app, without having to approve every individual payment along the way. This resembles the standing instruction an agent needs, although a recurring-payment service can use it without any AI making decisions.</p><p>Commercial Variable Recurring Payments went live on 2 June 2026 through the UK Payments Initiative, formed by 31 firms including major retail banks and described as the first new UK payment scheme since Faster Payments in 2008.</p><p>VRPs accounted for about 16 per cent of transactions through open banking, which lets authorised providers connect to bank accounts with customer consent, and grew 98 per cent year on year, against 351 million open banking payments in 2025. These broader figures differ from adoption of the new commercial scheme, initially covering regulated financial services, utilities and government, with e-commerce expected in the second half of 2026. Allowing an agent to choose payments within those limits still requires clear rules about who bears losses when it makes a mistake.</p><h3>Australia</h3><p>Australia offers a related approach. Its PayTo service lets customers see payment agreements in their banking apps and withdraw permission there. For an agent service, that is an appealing starting point because the customer already has somewhere familiar to check what they have allowed and stop it. PayTo has operated on the New Payments Platform since 2022. Its Mandate Management Service, operated by NPP Australia, keeps a central record of those agreements and checks accounts and available funds when an agreement is created.</p><p>PayTo and AP2 do different jobs, but both address the need to record limited authority and make it checkable. PayTo’s 301 per cent volume growth in the second half of 2025 shows increasing use of that payment infrastructure. It does not tell us how much spending an AI chose, because agent identity and authority still have to be connected to the agreement.</p><h3>India</h3><p>Where VRPs and PayTo provide arrangements that agents could use, India is considering explicit rules for agent payments. Its Unified Payments Interface, or UPI, lets people and businesses make instant payments between accounts. Reuters reported in early September 2026 that NPCI, the National Payments Corporation of India, was developing a Unified Agent Protocol for UPI payments without per-transaction human approval. A possible unveiling at Global Fintech Fest in Mumbai remained unconfirmed by NPCI, distinguishing the proposal from mechanisms already in use.</p><p>UPI Circle already lets an account holder authorise a secondary user to pay on their behalf, and the proposed agent model applies that role to software. Reserve Pay supports this by allowing funds to be set aside for several later payments, described as capped at around 10,000 rupees for 90 days. Used together, the two mechanisms could give an agent permission to pay from a limited amount set aside by the customer. The proposed rulebook would address responsibility when something goes wrong, while NPCI would check payment requests rather than decide whether a purchase was wise.</p><p>Pine Labs put its agent-payment offering, P3P, into production on UPI in June 2026, following a 2025 Razorpay, NPCI and OpenAI pilot using UPI Circle and Reserve Pay for ChatGPT payments. Mastercard completed an authenticated agentic transaction in New Delhi with Indian-bank cards, while Visa developed its own approach. For agents to use these different services, the providers need compatible ways to exchange payment instructions and verify permission.</p><p>UPI processed 24.51 billion transactions worth nearly 30 trillion rupees in August 2026, with volume up 22 per cent year on year and roughly two thirds consumer-to-merchant. Common delegation rules could therefore reach far beyond individual shopping integrations.</p><h3>Southeast Asia</h3><p>The question extends beyond domestic payments in Southeast Asia, where agents would also encounter systems connected across borders. The region starts with widespread payments through bank accounts and QR codes. By end-2025, ten countries had national QR standards, eight were connected across borders and 29 QR and person-to-person linkages were live. The systems include KHQR in Cambodia, QRIS in Indonesia, DuitNow in Malaysia and QR Ph in the Philippines, alongside PayNow in Singapore, PromptPay in Thailand and VietQR in Vietnam. They help customers scan to pay or identify the account receiving the money, but those functions do not themselves give an agent authority to spend.</p><p>Project Nexus would make these cross-border connections simpler. Instead of each national system building a separate connection to every other one, it would connect once to a shared arrangement and reach the others through it. Developed through the BIS Innovation Hub, with Nexus Global Payments based in Singapore, its founding systems are India, Malaysia, the Philippines, Singapore and Thailand. This helps a payment travel across borders, while leaving open the question of who gave the agent permission to send it.</p><p>Estimates put card reach below 15 per cent of potential customers in most ASEAN markets. By early 2025, QRIS had 56 million users and 38 million merchants, over nine in ten micro or small businesses; account-to-account payments represented 44 per cent of Thai e-commerce value. Google, Temasek and Bain’s e-Conomy SEA report projected digital payments reaching 73 per cent of total transaction value across the ten member states by 2030.</p><p>By June 2026, gateways, cross-border platforms and card networks were calling agentic commerce the next major change after QR payments. Wallet relationships offer a base for delegation, but suitability depends on controls and interfaces rather than reach alone; delegation is not automatically easier than through cards.</p><p>Mastercard reported authenticated agentic transactions and activity in Singapore and Malaysia during its April 2026 ASEAN expansion, following Singapore’s March transaction. National connectivity still lacks a common agent framework, although Singapore’s PayNow Gen2 study includes agentic commerce, with mandate design and delivery unresolved.</p><p>Taken together, these national and regional examples show two useful foundations. UPI Circle, VRPs and PayTo offer limited permission given beforehand, with ways to withdraw it, while regional wallets supply customer and merchant relationships. India’s reported initiative explicitly adds agent rules; the wider challenge is to identify the agent, check that each payment is permitted and establish how mistakes will be resolved.</p><h3>What does Singapore have?</h3><p>Singapore has work under way on both the payment connections and the safeguards, but its early transactions need to be assessed by the same test of what was delegated and who can use the service. DBS and Visa announced <a href="https://www.dbs.com/newsroom/DBS_is_first_bank_in_Asia_Pacific_to_pilot_Visa_Intelligent_Commerce_for_everyday_payments">real food-and-beverage purchases</a> using DBS/POSB cards on 16 February 2026 through payment processes controlled by the card issuer. On 4 March, Mastercard reported an agent <a href="https://www.mastercard.com/news/ap/en/newsroom/press-releases/en/2026/mastercard-delivers-its-first-live-agentic-transaction-in-singapore-with-dbs-and-uob/">booking a ride to Changi Airport</a> through hoppa, facilitated by CardInfoLink and involving DBS and UOB. That purchase used tokenised credentials and passkeys to secure confirmation, demonstrating agent-led execution with a person still approving the transaction.</p><h3>Domestic rails</h3><p>Those card-based trials are one starting point. Singapore’s domestic infrastructure offers several other useful components, each doing a different job. <a href="https://www.abs.org.sg/e-payments/fast">FAST</a> moves SGD between participating accounts almost immediately. <a href="https://www.abs.org.sg/e-payments/pay-now">PayNow</a> helps find the destination using an identifier such as a business’s Unique Entity Number, or UEN, rather than requiring the payer to enter an account number. <a href="https://www.imda.gov.sg/how-we-can-help/nationwide-e-invoicing-framework/invoicenow">InvoiceNow</a> carries structured invoices through Peppol, a network for exchanging business documents, so software can read the business information directly. Together, through the necessary service connections, they can help software read what is owed, identify the recipient and transfer the money.</p><p>Imagine connecting those pieces for a supplier payment. The agent receives an invoice, compares it with the order and delivery record, checks the supplier and prepares an instruction through an authorised bank or payment service provider. Afterwards it matches the payment result to the invoice. That last step is reconciliation, which establishes that the money and business records agree. The workflow also needs permission to initiate payment, checks on the recipient and a way to avoid paying twice.</p><p>GIRO is another familiar example of permission given in advance. A customer authorises future collections once, and payments settle in batches. Project Orchid explored Purpose Bound Money, where digital money carries spending conditions that a recipient can check. Alongside examples such as UPI’s budget mechanism and Australia’s mandate registry, these show that many useful pieces already exist. Putting them together for an agent still requires a clear account of what that agent may decide.</p><p>A consumer normally approves a PayNow payment inside an authenticated banking session, with digital-token approval reinforcing that channel since 2024. An agent cannot simply inherit that access because it knows the payment details. It needs a supported delegation or provider connection; until then, it can still do the useful work of preparing the payment for the person to approve.</p><p>The <a href="https://www.abs.org.sg/docs/library/mas-and-abs-chart-instant-payments-enhancements-with-paynow-generation-2-study.pdf">PayNow Gen2 study</a>, announced by MAS and ABS on 25 June 2026, explicitly includes agentic commerce among longer-term enhancements alongside requests asking a customer to pay, standardised information for matching payments to records, and very small payments. Foundational work was to begin in 2026, with a roadmap due by year-end, setting a direction for development without yet specifying how or when agents would receive standing permission to pay.</p><p>The organisations administering payment systems can help agree who is responsible when an agent makes a mistake and how customers obtain redress. Singapore Payments Network, or SPaN, has a role in administration and governance rather than processing and settlement, with the <a href="https://www.abs.org.sg/docs/library/abs-53rd-annual-dinner---speech-by-abs-chairman-mr-tan-teck-long-group-chief-executive-officer-ocbc.pdf">ABS chairman’s June 2026 speech</a> placing the start of operations in early 2027, updating the earlier end-2026 target. That gives SPaN a possible role in coordinating agent-payment rules, although that does not amount to an announced agent-payment protocol or certification scheme.</p><p>Singapore’s existing protections also need careful consideration before a service promises safe delegation. The <a href="https://www.imda.gov.sg/resources/press-releases-factsheets-and-speeches/press-releases/2024/implementation-of-shared-responsibility-framework">Shared Responsibility Framework</a> addresses a defined scope of phishing scams involving unauthorised transactions; it is not blanket reimbursement for every scam-induced payment. If an agent uses a valid credential after being deceived, whether that payment falls within existing protections depends on the facts and applicable rules. Builders should not assume an agent’s signature settles the customer’s rights, or that choosing to use an agent makes every resulting loss the customer’s responsibility.</p><p>The same uncertainty arises when an agent initiates a payment based on something it invented. The agent itself is not a legal person that can compensate the customer. IMDA’s <a href="https://www.imda.gov.sg/-/media/imda/files/about/emerging-tech-and-research/artificial-intelligence/agents-legal-responsibility.pdf">discussion paper on legal responsibility for AI agents</a> examines how contract and negligence may apply, while highlighting the difficulty of identifying fault across several providers. It does not create a rule assigning every loss to one party. A deploying business must manage its agent operationally, but that responsibility is distinct from a legal finding that it must pay every claim.</p><p>The allocation depends on the failure. An agent provider’s promised checks, the deployer’s chosen permissions, a merchant’s representations and a payment provider’s enforcement duties could each matter. A model developer’s responsibility would likewise depend on applicable duties and the connection between its conduct and the loss, rather than the mere use of its model. Customer instructions and conduct may also be relevant, but choosing an agent does not automatically make the customer responsible for every error. Where reasonable safeguards were taken and an unexpected error still occurred, allocation of the loss remains particularly difficult.</p><h3>SAFR</h3><p>Clearer operational controls can help prevent these failures and preserve evidence when they occur, even though they cannot settle every liability question. <a href="https://file+.vscode-resource.vscode-cdn.net/Users/sausheong/projects/agentic-payments/Users/sausheong/Downloads/SAFR.pdf">Safeguards for Agentic Finance at Runtime</a>, or SAFR, describes a checkpoint between an agent and the systems it acts on. Before payment, the checkpoint asks whether the instruction fits the applicable rules. Published in July 2026 under MAS’s <a href="http://buildfin.ai/">BuildFin.ai</a> initiative, version 1.0 is an industry reference for institutions to implement, not regulatory approval or a ready-made service. It offers enough detail to begin building controls for a clearly defined task, while dependable operation still has to be demonstrated in each institution.</p><p>The agent supplies a Governance Envelope describing the proposed action and its supporting evidence. Four components check identity, retrieve rules, decide what may proceed and keep a record that reveals tampering. SAFR calls them Agent Identity, the Controls Repository, the Disposition Engine and the Audit Log. Evidence must be checked against its origin, since an agent’s convincing account of its actions may still be false. The result is Deny, Escalate to a person, Auto-Execute or Observe, which permits the action while flagging it for monitoring. Defined rules determine the outcome, even where assessing evidence involves judgement, and every new action needs its own check.</p><p>Ant International, Circle, HSBC, J.P. Morgan Chase, Manulife, Mastercard, OCBC and Visa contributed to the paper. Its payment examples show approaches taken by Ant, Circle, Mastercard and Visa; OCBC and Bank of Singapore’s Source of Wealth Assistant illustrates compliance review with human validation, while Manulife’s sales-support example has no autonomous execution path into financial systems. These are useful foundations, but contribution and inclusion as a case study do not establish that each organisation has fully deployed SAFR or passed a common assessment.</p><p>Independent providers are also building around the approach. <a href="https://kla.digital/safr">KLA</a> describes controls for agents on its own runtime and a four-week engagement for a qualified, narrowly scoped implementation, while its customer-owned-agent route remains in development. <a href="https://agenticrail.nz/spec/safr/">AgenticRail</a> maps its system to SAFR but identifies differences, including the absence of separate Escalate and Observe outcomes. These are providers’ descriptions, not evidence of MAS certification or widespread institutional adoption.</p><p>The next stage is learning from deployments. The <a href="https://ebs.publicnow.com/view/6037659EA672BDC2DB84F27E31C443ADFD6BA78A">MAS launch announcement</a> invites industry contributions and envisages the Future of Finance Institute supporting pilots and sandbox experimentation. It gives no firm date for a subsequent version or broad rollout. The <a href="https://mondovisione.com/media-and-resources/news/written-reply-to-singapore-parliamentary-question-on-agentic-ai-in-financial-ser-202685/">August parliamentary reply</a> likewise describes SAFR as a potential approach alongside broader AI risk-management expectations, without setting a mandatory adoption deadline. A vendor’s implementation schedule should therefore not be mistaken for a national timetable.</p><p>SAFR or a similar framework can work alongside AP2 mandates, model safeguards, compliance systems and payment rails. The mandate records permission; the institution’s checkpoint tests whether this action meets it. Institutions still need to configure rules, authenticate evidence, staff reviews and test failures. <a href="https://www.imda.gov.sg/resources/press-releases-factsheets-and-speeches/factsheets/2026/updated-model-ai-governance-framework-for-agentic-ai">IMDA’s agentic AI framework</a> addresses the wider risks of agents and third-party systems working together. For the core payment problem, these controls are what could replace routine human approval with a check at every action. They must also detect suspicious behaviour within an otherwise valid mandate and let an authorised operator stop the agent. The practical milestone is reliable handling of real tasks, scams, mistakes and withdrawn permissions, rather than simply declaring alignment with a framework.</p><h3>Settlement experiments</h3><p>Alongside these checks on what an agent may do, Singapore is exploring whether digital forms of money can make the payment itself easier for software to carry out. MAS’s <a href="https://file+.vscode-resource.vscode-cdn.net/Users/sausheong/projects/agentic-payments/agentic-payments.md#611-tokenised-settlement-programmes-relevant-but-not-automatically-agentic">BLOOM initiative</a> includes agentic payments among uses for transfers between institutions, using bank obligations represented as digital tokens and well-regulated stablecoins. Stablecoins are digital tokens designed to track the value of a currency. Conditional settlement alone does not establish that an agent makes or executes an authorised decision.</p><p>The same distinction applies to StraitsX’s XSGD and XUSD, stablecoins linked to the Singapore and US dollars respectively, which <a href="https://www.straitsx.com/blog-post/xsgd-and-xusd-live-on-solana">went live on Solana</a> on 31 March 2026. Solana is a blockchain network on which those tokens can move. Their availability establishes infrastructure, while the more concrete agent experiment came through <a href="https://www.straitsx.com/blog-post/straitsx-launches-agentix-playground-to-accelerate-the-future-of-agentic-payments">AgentiX Playground</a> in August, when 67 builders across 40 teams used XSGD on another blockchain, the live Avalanche C-Chain network, to explore software connections through MCP and payments through x402 and cards. Spending controls and signed-approval checking were among the examples, providing prototype evidence on real infrastructure without establishing sustained commercial use.</p><p>These experiments establish that builders can connect agents to real payment infrastructure. Turning that into a service means finding tasks customers return for, delivering reliably and handling failures. Before looking at how the five opening scenes could work, we also need to consider the legal responsibilities that come with letting an agent spend.</p><h3>Does the law need to catch up?</h3><p>Giving an agent permission to pay also means deciding who takes responsibility when it gets something wrong. If the family’s grocery agent exceeds its budget, buys from a fraudulent shop or orders something nobody asked for, the payment might still go through correctly. The bank has moved the money, but that does not settle whether the purchase was authorised or who should bear the loss. The technical controls need a legal arrangement behind them that customers, merchants and payment providers can rely on.</p><p>Singapore already has a foundation for this. The <a href="https://sso.agc.gov.sg/act/eta2010">Electronic Transactions Act</a> recognises contracts formed through automated systems without a person reviewing every action. We therefore do not need to make automated purchasing legal from scratch. What remains harder is establishing how far the agent’s authority extends, when another party can rely on it, and what happens when the agent acts beyond it. A protocol can record permission and a digital signature can help prove where an instruction came from, but neither decides who owes the customer a refund.</p><p>Consider the café agent paying for coffee beans after mistakenly concluding that they have arrived. If the supplier falsely claimed delivery, the dispute concerns the supplier’s conduct. If the agent invented a delivery confirmation, we need to examine the service that allowed that claim to trigger payment. The provider might have failed to enforce a promised check, or the café might have configured the system to pay without one. Calling the mistake a hallucination does not answer these questions. Responsibility depends on what each party undertook to do and how its actions contributed to the loss.</p><p>The challenge becomes sharper when an agent is deceived while staying within its spending limits. A fraudulent invoice for $80 may satisfy a $100 cap, even though the owner never intended to pay a scammer. This is why the legal distinction between an unauthorised payment, an authorised but mistaken purchase, and a payment induced by deception matters. Each can lead to different remedies, although the customer experiences all three as money that should not have left the account.</p><p>Other jurisdictions are approaching these issues through a mixture of existing law, targeted reform and supervised testing. The <strong>United Kingdom</strong> has put agentic payments explicitly into its <a href="https://www.gov.uk/government/consultations/modernising-payment-services-regulation">consultation on modernising payment services regulation</a>. Its broader reform programme also considers changes to strong customer authentication, the checks used to verify customers during payments. The question is how to preserve meaningful consent and security when the customer is not present for each transaction. Alongside that legal work, the Government is considering agentic payments in future payment infrastructure, while FCA sandbox participants explore agent-led payments and commerce. These are steps towards a framework, rather than a declaration that the liability questions have been settled. <a href="https://questions-statements.parliament.uk/written-questions/detail/2026-09-01/25983">The Treasury’s explanation</a> connects those efforts.</p><p>The <strong>European Union</strong> is strengthening the surrounding payment protections through its PSD3 and Payment Services Regulation reforms. The <a href="https://www.consilium.europa.eu/en/press/press-releases/2025/11/27/payment-services-council-and-parliament-agree-to-step-up-the-fight-against-fraud-and-increase-transparency/pdf/">provisional agreement</a> includes stronger fraud prevention, checks matching account numbers to names, and liability where payment providers fail to fulfil specified preventive obligations. These measures were not designed solely for AI agents and should not be mistaken for a complete agentic payment regime. They nevertheless point towards an important principle for delegated payments. Providers should have concrete duties to prevent foreseeable harm, rather than treating a valid payment instruction as the end of their responsibility.</p><p><strong>Australia</strong> has taken a broader consumer law approach. Its <a href="https://treasury.gov.au/review/ai-australian-consumer-law">review of AI and the Australian Consumer Law</a> examined how existing protections, remedies and liability arrangements apply to AI goods and services. It concluded that the law, together with other legislation, remains capable of protecting consumers, while calling for continued monitoring. The lesson is useful for Singapore. New technology does not automatically require an entirely new legal regime, but existing rights must remain practical when the product making the mistake is software acting on someone’s behalf.</p><p>There is also international work on the contracts themselves. The <a href="https://uncitral.un.org/en/mlac">UNCITRAL Model Law on Automated Contracting</a> gives countries a template for recognising automated transactions, attributing their outputs to people or organisations, and addressing certain unexpected outcomes. It is a model for national legislation, not a law that automatically applies everywhere. Its relevance grows when the research agent buys data from overseas providers, where the parties may otherwise have different assumptions about whether an automated agreement is binding.</p><p>Singapore is working on both governance and legal responsibility. IMDA’s <a href="https://www.imda.gov.sg/resources/press-releases-factsheets-and-speeches/press-releases/2026/new-model-ai-governance-framework-for-agentic-ai">Model AI Governance Framework for Agentic AI</a> recommends limits on agents’ powers, technical controls and meaningful human accountability. Its separate <a href="https://www.imda.gov.sg/-/media/imda/files/about/emerging-tech-and-research/artificial-intelligence/agents-legal-responsibility.pdf">discussion paper on legal responsibility</a> examines how existing civil liability principles apply across developers, deployers and users, including situations where an agent behaves unexpectedly despite safeguards. The paper explores the difficulties without prescribing a new liability regime.</p><p>SAFR or a similar framework can help put those governance expectations into practice by checking proposed actions and retaining evidence. That evidence could establish whether the family’s spending limit was active, whether the agent exceeded it and which service allowed the payment through. But a governance framework is not a compensation scheme. Following it does not, by itself, determine liability or give the customer an automatic right to reimbursement.</p><p>The most useful legal changes would therefore be targeted. Singapore should review whether the Electronic Transactions Act’s limited relief for <strong>human input errors</strong> needs to address mistakes generated by agents, while protecting merchants from customers simply disowning valid purchases. Payment rules should specify how delegated permission is granted, enforced and withdrawn. Consumer protection arrangements should address agent-induced scams and make clear which safeguards providers cannot disclaim through their standard terms. These are changes worth considering, rather than reforms already announced.</p><p>Dispute handling deserves equal attention. Customers should not have to move between a bank, merchant and agent provider, each blaming another participant. A workable service needs an identifiable party to receive the complaint, access to the relevant records and a route to an enforceable remedy. Government grants need an additional check because authority to execute a payment does not necessarily include authority to decide someone’s entitlement. That question must be resolved under the particular grant scheme, with a way for applicants to challenge mistakes.</p><p>Singapore has begun the necessary work, but guidance needs to lead to arrangements that people can actually use. Banks, payment providers, agent developers and regulators should agree on standard permission terms, minimum safeguards and responsibility for losses, then test them in services handling real disputes as well as successful payments. We do not need to wait for every legal uncertainty to disappear. We do need to stop leaving the customer to discover who is responsible only after the money has gone. With those responsibilities in view, the five opening scenes give us concrete ways to examine what we can build and what still needs to change.</p><h3>How could the five cases work in Singapore?</h3><p>For each of the five scenes, there is a useful first version we could build and a further gap to unattended payment. The starting point is strongest where one organisation can choose the suppliers, set the rules and arrange payment access. The harder cases involve several banks, merchants or people whose systems and permissions must work together. The practical question is which connections we can make ourselves and which require a bank, wallet or merchant to participate.</p><p>The ratings estimate the difficulty of building and operating a dependable Singapore service, including engineering, provider access, payment permission and recovery when something goes wrong. <strong>1 means trivial and 10 means impossible under the stated conditions.</strong> The unattended scores assume a capable team and a cooperating business or agency, but include the work of obtaining provider access. Keeping a person at the approval step makes several cases much easier; none of the bounded versions is inherently impossible, although a missing payment permission can stop a particular implementation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YtgEXlcAht61nk26sptWMg.png" /></figure><h3>Household groceries</h3><p>For this consumer-to-merchant case, I would start with a shared shopping list and past orders, letting the family correct quantities and priorities. The agent could compare prices and delivery slots within the $150 weekly budget, including fees. One supermarket would be a manageable beginning before adding a second for urgent items. The family would decide which shops it may pay, what substitutions are acceptable and what can wait. Could it postpone rice to cover an extra delivery fee for milk, or should it ask? An unfamiliar shop offering urgent delivery also raises a scam risk, so permission to switch retailers should not automatically permit payment to any website the agent finds.</p><p>The service would reserve money for each order against the same weekly allowance, recheck basket changes and establish whether a failed order had been charged before replacing it. We could begin with family approval, then allow routine purchases under permission they can limit and withdraw. <a href="https://ap2-protocol.org/ap2/specification/">AP2</a> or <a href="https://verifiableintent.dev/">Verifiable Intent</a> could record that permission, but shops and payment providers still have to accept it. Retailers also need to provide catalogue and checkout access, directly or through <a href="https://github.com/agentic-commerce-protocol/agentic-commerce-protocol">ACP</a> or UCP; appearing within an assistant’s shopping service involves separate participation requirements such as <a href="https://developers.google.com/merchant/ucp">Google’s UCP programme</a>.</p><p>Singapore still needs a service that connects participating retailers and payment providers and lets families sign up to use it. Stripe’s <a href="https://docs.stripe.com/agentic-commerce/concepts/shared-payment-tokens?agent-seller=agent">Shared Payment Token country list</a> excludes Singapore, <a href="https://www.visa.com.sg/about-visa/newsroom/press-releases/visa-launches-agentic-ready-programme-in-singapore-with-13-banks-and-fintech-partners.html">Visa’s Agentic Ready programme</a> involves controlled testing, and <a href="https://www.antom.com/news/ant-internationals-antom-debuts-agentic-payment-solution-pioneering-apm-checkout-solution-and-trusted-ai-for-secure-transactions">Antom’s proposed flows</a> need confirmation of local support. A small partnership could connect approved shops to a bank, card issuer or wallet, with an operator responsible for the shared budget, failed orders, extra charges and refunds. Shopping freely across unfamiliar retailers requires wider acceptance of that arrangement. The family would also need prompt receipts, an easy stop control and a clear contact for disputed charges, with responsibility for failed safeguards agreed before unattended spending begins.</p><h3>Splitting the bill</h3><p>The dinner example moves the problem from paying shops to paying other people. Once the restaurant is paid, settling dinner becomes a person-to-person payment. We could already build an agent that reads a receipt photograph, allocates dishes, GST and service charge, and explains each proposed share. Friends could correct mistakes and agree how to split shared dishes before approving their own PayNow transfers. That saves arithmetic and chasing without giving the agent access to anyone’s money.</p><p>To settle automatically, each friend would need standing permission limited to named recipients and amounts per meal and month. Their agent would check the receipt, what they agreed and the destination account before using an authorised bank or wallet connection. Another friend’s request is not permission to debit an account. A compromised friend’s agent could send a convincing false claim, so the recipient’s identity alone cannot establish that the debt is real. Neither a PayNow QR nor an MCP tool supplies that authority, and AP2 does not provide agent-to-agent mandate delegation.</p><p>Singapore’s gap is a generally available arrangement through which different banks recognise those personal instructions, allow easy withdrawal of permission and resolve disputed claims or mistaken transfers. One provider could begin with enrolled users, but five friends using different banks is harder, explaining the high difficulty score. UPI Circle, VRPs and PayTo offer design ideas; their mandates and Project Nexus do not grant access to Singapore accounts. <a href="https://www.abs.org.sg/docs/library/mas-and-abs-chart-instant-payments-enhancements-with-paynow-generation-2-study.pdf">PayNow Gen2</a> creates room for this work without yet supplying the arrangement. Until those arrangements exist, the agent can prepare each transfer for its owner to approve.</p><h3>Café replenishment</h3><p>The café has a more contained starting point than friends spread across several banks. Its business-to-business purchases can build on existing supplier approvals and spending limits. An agent could use stock records to compare prices and delivery times from three trusted roasters, then choose the best offer for the required bean grade and quantity within the weekly budget. We could start with the owner releasing payment, allowing routine orders to proceed unattended once the owner and provider agree the boundaries.</p><p>A connection such as <a href="https://www.dbs.com.sg/corporate/solutions/rapid">DBS RAPID</a> supports account verification, payments and collections subject to access and authorisation; a restricted card could also work with a supporting supplier and issuer. Neither comes automatically with a business account. Aspire or Nium for business payments, and Stripe Issuing or Lithic for cards, are candidates to investigate rather than interchangeable Singapore routes, since geography, eligibility and controls determine access.</p><p>Once payment access is in place, controls built around <a href="https://file+.vscode-resource.vscode-cdn.net/Users/sausheong/projects/agentic-payments/Users/sausheong/Downloads/SAFR.pdf">SAFR</a> or a similar framework could check a new agent’s structured proposal, called a Governance Envelope in SAFR, or intercept an existing agent’s instructions through a gateway between it and the supplier or bank. Trustworthy task records would support checks on quantity, substitutions, spending and action rates. A forged invoice or compromised supplier email could redirect payment, so changed bank details need confirmation through an independently trusted contact, rather than the message requesting the change. Orders, payments and deliveries would remain separate records so shortages, rejected beans and refunds could be resolved after payment. A delivery confirmation should come from a trustworthy receiving record, so an agent cannot trigger payment merely by claiming that the goods arrived. A subsequent dispute could then distinguish a supplier failing to deliver from the agent falsely reporting delivery.</p><p>The remaining work in Singapore is mainly connecting the café’s systems and running the service reliably. Stock levels, prices and delivery records must be reliable, the bank must approve the payment connection, and someone must handle exceptions. A provider could package those pieces without waiting for a new national payment system. The owner and provider would also need to agree who bears losses if those controls fail. The question for a small café is whether the service costs less than the work it saves, including the cost of fraud and recovery.</p><h3>Government grants</h3><p>An agency can also define rules and arrange payment access, but its agent must first decide whether someone is entitled to public money. A grant is a disbursement, so I would begin with that eligibility decision. An agent could check an application for missing documents, compare evidence with the scheme’s criteria and prepare a recommendation and payment instruction. A caseworker could trace its reasoning to the documents before approving it, keeping the agency’s decision distinct from the agent’s interpretation.</p><p>Unattended release would require the correct version of the rules, verified recipients and accounts, and checks against instalments already paid. Conflicting evidence, uncertain conditions or changed bank details would go to an authorised reviewer, with a deadline and an appeal route. SAFR or a similar framework could guide those checks and records, but adopting it cannot grant powers to the agent or remove a caseworker whom the scheme requires. The model’s confidence alone is insufficient, whether documents are forged or the agent invents an eligibility fact or misstates a rule. The agency should investigate and correct its decision through the scheme’s review process, while any claim against a technology provider is assessed separately. Protecting the applicant also means preserving a way to challenge an incorrect rejection, not merely preventing money reaching an ineligible recipient.</p><p>The remaining gap for each Singapore agency is permission to delegate the relevant decisions and evidence that the system can make them reliably. The scheme needs named responsibility for errors, tests against reviewed cases, investigation of disagreements and timely human handling of exceptions. It also needs an authorised connection from decisions to disbursement. Faster transfers and signed mandates cannot settle those questions, and the larger-value PayNow sandbox concerns payments to government rather than permission to award and release grants.</p><h3>Buying data and compute</h3><p>The research example returns us to purchasing, with software buying a service it can use immediately. For this machine-to-machine payment, imagine a research agent paying for a useful dataset from a small task budget rather than stopping for someone to open an account. We could begin with trusted APIs, interfaces for software services, using x402 and a compatible <a href="https://docs.x402.org/core-concepts/facilitator">facilitator</a> or <a href="https://mpp.dev/">MPP’s SDK</a>. The operator would keep keys and funding controls outside the model, restrict recipients and resources, and reserve money before concurrent requests. Receipts would link to requests and results; repeated failures or useless responses would stop further spending, while uncertain payments would be checked before retrying.</p><p>A Singapore operator first needs an approved way to fund payments and suppliers that accept the chosen payment method. Buyers and sellers need compatible assets, networks and providers; XSGD’s availability does not mean every x402 service accepts it. Stripe’s <a href="https://docs.stripe.com/payments/machine">machine-payment documentation</a> requires approval for non-US stablecoin access and applies country restrictions to its Shared Payment Token card path. Minimum payments of US$0.50 for cards and 0.01 USDC, about one US cent, mean smaller calls need grouping or another supported arrangement. <a href="https://www.mastercard.com/us/en/news-and-trends/press/2026/june/mastercard-launches-agent-pay-for-machines.html">Agent Pay for Machines</a> offers a further partner route, with access and supported uses to be agreed.</p><p>A service limited to known suppliers could be assembled without waiting for a national agent-payment scheme. Using it in a business also means funding the payment account or acquiring the tokens the service accepts, protecting keys and matching receipts to accounts. Letting it discover and pay unfamiliar providers is a bigger step, requiring dependable quality checks and recovery for missing or unusable results. A provider that takes payment but returns fabricated or useless data can cause harm even while staying within the budget. Delivery checks, spending cut-offs and agreed refund or service-credit terms are part of closing that gap.</p><h3>What ties these services together?</h3><p>Across the five cases, the suppliers, payment methods and consequences differ, but the same questions keep returning. The first is what the agent may do and who checks. Each service needs permission that people and software can understand, covering recipients, purpose, total spending, expiry, substitutions and exceptions. Those rules need owners. In an institution using SAFR or a similar framework, risk and compliance leadership would set the permitted delegation, action rates and evidence requirements. A human reviewer must have the time and authority to decide, including outside office hours where necessary; a timeout should block the action or send it to a senior reviewer.</p><p>The four stages in the diagram need to remain connected even when different providers handle them. Keeping the permission checkpoint separate from the payment connector lets the same spending policy govern a bank payout, restricted card or x402 purchase. Each connector still needs its own funding, settlement and recovery arrangements.</p><p>The next is whether the payment actually happened. The software needs a shared budget and lasting payment references that distinguish an instruction being prepared or approved from one submitted, settled or failed. A missing reply calls for investigation before retrying. Supplier-account changes need independent checks, and refunds must link back to the original payment and any money already returned. Invoice matching and reconciliation can provide value before the agent has authority to move money.</p><p>Even a completed payment may leave the task unfinished. A hotel booking may be useless if the flight failed, just as a paid dataset may be unusable. <a href="https://file+.vscode-resource.vscode-cdn.net/Users/sausheong/projects/agentic-payments/agentic-payments.md#8-what-remains-technically-and-operationally-unresolved">Recovery, cancellation, delivery evidence and escalation</a> belong alongside purchase terms and order acknowledgements. <a href="https://file+.vscode-resource.vscode-cdn.net/Users/sausheong/projects/agentic-payments/agentic-payments.md#9-economics-and-a-practical-implementation-approach">Starting with preparation and confirmed execution</a> lets a team judge whether greater autonomy saves enough to cover inference, integration, funding, reconciliation, losses and support.</p><p>Customers also need understandable terms explaining the permission they grant, responsibility for failures and routes for complaints, refunds and compensation under the applicable rules. Logs should preserve enough evidence to resolve a dispute without exposing unnecessary personal information. Notifications and a readily available stop control let the customer supervise the arrangement without being asked to approve every payment. Asking for confirmation on every transaction would avoid the central delegation problem rather than solve it.</p><p>A service should give the customer one clear place to raise a dispute and track its progress. The operator should preserve the original evidence, stop further suspect payments and explain which facts are being investigated. Depending on the payment’s status and the applicable rules, the response might be cancellation before completion, a merchant refund, a card dispute or a claim against the agent service. Recovery after settlement should not be described as a guaranteed reversal.</p><p>For a hallucination, the review should establish what the agent invented and whether the payment relied on it, rather than ask the same model to justify itself afterwards. The customer should receive an understandable decision, the reasons for any refusal and the available escalation route. Providers should coordinate that investigation so the customer does not have to identify which software component failed. Any interim refund, compensation or allocation of loss between providers needs an explicit contractual or legal basis.</p><p>The permission record, provider controls, institutional checks and dispute process therefore need to work together. Connecting them is what turns a payment demonstration into a dependable service.</p><h3>Is Singapore moving fast enough?</h3><p>Singapore has enough to begin, but we should not be comfortable if every new service still needs a bespoke pilot. The goal is for businesses and customers to delegate routine payments safely through services they can sign up for. Café purchasing and paid research give us practical places to start, using existing payment connections and SAFR or a similar framework to guide the controls.</p><p><a href="https://newsroom.mastercard.com/news/ap/en/newsroom/press-releases/en/2026/mastercard-powering-asean-s-ai-ambitions-in-the-future-of-payments/">Singapore and Malaysia were among Mastercard’s early ASEAN implementers</a>, but other markets are turning their foundations into usable arrangements. Amazon offers <a href="https://www.aboutamazon.com/news/retail/amazon-rufus-ai-assistant-personalized-shopping-features">target-price purchasing</a>, India explicitly includes software in <a href="https://www.npci.org.in/uploads/UPI_OC_No_201_B_FY_2025_26_Addendum_to_NPCI_UPI_2024_25_OC_201_Introduction_of_Io_T_devices_software_on_UPI_Circle_09ec83c893.pdf">UPI Circle</a>, and Australia’s <a href="https://www.auspayplus.com.au/solutions/payto-faqs">PayTo</a> and the UK’s <a href="https://www.modulrfinance.com/newsroom/modulr-launches-cvrp-collections-hub">commercial VRPs</a> provide limited advance payment authority. China’s wallet platforms bring established customer and merchant relationships. These are different forms of progress, not proof of widespread autonomous spending, but they give Singapore little reason to wait.</p><p>Banks and payment providers should publish clear eligibility, onboarding times and spending controls, so developers can plan a service. Merchants should make selected catalogues and replenishment flows available to agents. Builders should bring real customers and repeatable tasks, starting with approved suppliers and limited budgets. The result should be an arrangement the next business can join without negotiating everything again.</p><p>Risk teams should test scams, malicious instructions, duplicate payments, hallucinations and withdrawal of permission, then measure repeat usage, losses and recovery. Customers need one clear route for disputes. Scheme owners should give agentic capabilities explicit milestones and accountable owners within <a href="https://www.abs.org.sg/docs/library/mas-and-abs-chart-instant-payments-enhancements-with-paynow-generation-2-study.pdf">PayNow Gen2</a>, whose announced foundational milestones do not yet promise autonomous PayNow. Work on services using existing payment arrangements can proceed alongside it.</p><p>I would expect wider progress in business purchasing, machine services and selected merchant partnerships during 2026–2027. Everyday use during 2028–2030 remains a tentative forecast, dependent on provider access, merchant participation, workable safeguards and clear responsibility for mistakes. We should use that horizon to set near-term delivery goals, not postpone action.</p><p>If 2027 brings mainly more demonstrations while businesses still struggle to obtain payment access, we will be moving too slowly. Singapore need not invent every protocol to put them to work. Banks, payment firms, merchants and builders should choose a useful task, make the payment connection available and get a dependable service into customers’ hands.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6c05e99568f8" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Build and Deploy an MCP App]]></title>
            <link>https://medium.com/@sausheong/how-to-build-and-deploy-an-mcp-app-c07ee1d17191?source=rss-a358058b2410------2</link>
            <guid isPermaLink="false">https://medium.com/p/c07ee1d17191</guid>
            <category><![CDATA[mcp-server]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[claude]]></category>
            <category><![CDATA[chatgpt]]></category>
            <category><![CDATA[mcp-app]]></category>
            <dc:creator><![CDATA[Sau Sheong]]></dc:creator>
            <pubDate>Thu, 03 Sep 2026 01:38:29 GMT</pubDate>
            <atom:updated>2026-09-03T01:38:29.009Z</atom:updated>
            <content:encoded><![CDATA[<p><em>A step-by-step guide to building WeatherSG in TypeScript and running its interactive weather map inside ChatGPT and Claude.</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*io3eW1iq9dz7Id3td4vD4A.png" /></figure><p>A weather question usually ends with a sentence. Ask whether it is raining in Singapore and an assistant can tell you that several stations are recording rain. That answer is useful, though it does not show where the rain is falling. A commuter in Jurong and a cyclist in Tampines may be dealing with quite different skies.</p><p>WeatherSG turns the answer into an interactive map inside the conversation. The model chooses a tool, the server fetches current data from Singapore’s public weather APIs, and the host renders a React interface without sending the user to another tab.</p><p>I used WeatherSG as a simple project for learning MCP Apps. It has enough moving parts to show how the architecture works, while the business logic remains familiar. By the end of this guide, you will have built the server, browser interface, HTTP transport, container and production deployment. You will also connect the same endpoint to ChatGPT and Claude.</p><p>The working example is in the WeatherSG project. The production endpoint used while checking this article was <a href="https://weathersg.sausheong.dev/mcp.">https://weathersg.sausheong.dev/mcp.</a></p><h3>What is an MCP App?</h3><p>MCP stands for Model Context Protocol. It is an open protocol that gives an AI host such as ChatGPT or Claude a standard way to discover and call tools provided by another server. Instead of writing one integration for ChatGPT, another for Claude and a third for every other host, you describe the tools once through MCP.</p><p>An MCP App extends one of those tools with an interface. The tool still accepts arguments and returns data, but it can also point the host to an HTML resource. The host loads that resource in a sandboxed iframe beside the conversation. JavaScript in the iframe exchanges JSON-RPC messages with the host through the MCP Apps postMessage bridge.</p><p>This gives an MCP App three cooperating parts.</p><ol><li>The <strong>MCP tool</strong> tells the model what the application can do and returns model-readable results.</li><li>The <strong>UI resource</strong> supplies the HTML, CSS and JavaScript that the user sees.</li><li>The <strong>host bridge</strong> carries tool results, user actions and context between the iframe and the AI host.</li></ol><p>The interface does not replace the conversation. The model can choose the right tool from the user’s request, while the interface handles tasks that are awkward in text. A map can be panned, a chart can be filtered and a form can collect several related values without a long exchange of prompts.</p><p>The MCP Apps specification is an optional extension to MCP. A tool should remain useful when a host cannot render its interface. This is why WeatherSG returns normal text and structured weather data as well as the map.</p><h3>How MCP Apps came about</h3><p><a href="https://www.anthropic.com/news/model-context-protocol">Anthropic introduced MCP on 25 November 2024</a> to address a growing integration problem. Models were improving, but they remained cut off from much of the data and software people needed them to use. Connecting every assistant to every data source with a custom adapter did not scale. MCP supplied a common protocol for those connections.</p><p>The first version concentrated on context and actions. Servers could expose resources and tools, and models could use their results. This worked well for retrieving a document or performing a discrete action. It was less satisfactory when people needed to inspect a large result, manipulate it directly or make a visual choice. Returning hundreds of rows as text is technically possible, but sorting, filtering and selecting them through repeated prompts is slow.</p><p>Developers began experimenting with interfaces returned by MCP tools. The community-led MCP-UI project and OpenAI’s Apps SDK showed that interactive components could sit inside an AI conversation. Their approaches were similar, but a shared specification was needed if developers were to build an interface once and run it in several hosts.</p><p>The MCP project <a href="https://modelcontextprotocol.io/seps/1865-mcp-apps-interactive-user-interfaces-for-mcp">proposed MCP Apps in November 2025</a>. The proposal brought the earlier work together as an optional, backwards-compatible MCP extension. On 26 January 2026, <a href="https://blog.modelcontextprotocol.io/posts/2026-01-26-mcp-apps/">MCP Apps became the first official MCP extension</a>, with support announced for Claude, ChatGPT, Goose and Visual Studio Code.</p><p>The aim went beyond richer chat responses. MCP had standardised the connection between models and tools, but there was still a gap between what a tool could do and what a person could see or control. MCP Apps closes that gap while keeping the model involved. The host owns the conversation and security boundary, the server owns the tool and data, and the embedded interface handles direct interaction.</p><p>That separation also explains why the interface uses a sandbox and a message bridge instead of behaving like an ordinary web page. The host controls which capabilities are available, tool calls remain subject to its consent and security rules, and the same application can run in more than one compatible host. OpenAI’s <a href="https://developers.openai.com/plugins/build/chatgpt-ui">MCP UI documentation</a> describes the same standards-based arrangement for ChatGPT.</p><h3>How an MCP App works from prompt to interface</h3><p>Follow one request through the whole system. Suppose the user asks ChatGPT or Claude to show the Singapore weather map.</p><ol><li><strong>The host connects to the MCP server.</strong> ChatGPT or Claude opens an MCP session with WeatherSG and asks which tools are available. The server describes each tool, its input fields and what it does.</li><li><strong>The model chooses a tool.</strong> The host gives those tool descriptions to the model. From the words “show” and “map”, the model selects show_singapore_weather_map and supplies its arguments. For example, it may set layer to all.</li><li><strong>The host calls the server.</strong> The call travels to WeatherSG through the MCP transport. In production, this is an HTTPS request to the /mcp endpoint using Streamable HTTP.</li><li><strong>The server does the work.</strong> WeatherSG fetches the forecast and rainfall readings from <a href="http://data.gov.sg/">data.gov.sg</a>, validates them and converts them into one WeatherSnapshot. The tool returns ordinary text for the model and structured data for the interface.</li><li><strong>The host finds the interface.</strong> The map tool’s metadata contains a ui:// resource URI. This tells the host that the result has an MCP Apps interface. If the host has not already fetched it, it asks WeatherSG for the resource and receives the bundled HTML, CSS and JavaScript.</li><li><strong>The host creates the iframe.</strong> ChatGPT or Claude places the HTML in a sandboxed iframe inside the conversation. The application cannot reach into the host page or read the host’s cookies.</li><li><strong>The bridge delivers the result.</strong> The interface connects to the host through JSON-RPC messages sent with postMessage. The MCP Apps SDK handles the connection details. When the host passes the tool result to the iframe, WeatherSG receives it through app.ontoolresult and draws the map.</li><li><strong>Further actions follow the same boundary.</strong> A filter that only changes the visible markers can run inside the iframe. If the interface needs fresh server data, it can ask the host to call another MCP tool. It can also send a follow-up message or add context for the model. These actions go through the bridge rather than accessing ChatGPT or Claude directly.</li></ol><p>There are therefore two participants making decisions. The model interprets the request and chooses a tool. The user works with the returned interface. The host sits between both of them, controls the iframe and carries messages to the server. Your MCP server remains responsible for the application logic, data access and permissions.</p><h3>What you will build</h3><p>WeatherSG puts this pattern into practice with two tools. One provides the ordinary model-readable result and the other adds the map.</p><ul><li>get_singapore_weather returns structured weather data for factual questions.</li><li>show_singapore_weather_map returns the same data and asks the host to render the interactive map.</li></ul><p>We keep both tools because a question such as “Is it raining anywhere?” does not always need a map. A request such as “Show me where it is raining” does. Narrow tools and direct descriptions give the model a better chance of choosing correctly.</p><p>The map is progressive enhancement. A host that supports MCP Apps can render it. A host that only understands normal MCP tools still receives useful text and structured data.</p><h3>Why I used TypeScript</h3><p>I usually write this sort of backend in Go. I chose TypeScript for WeatherSG because the server and browser interface can then use the same language, types and build system. The WeatherSnapshot contract can travel from the weather client to the MCP tool and into React without being maintained twice.</p><p>The backend could certainly be written in Go, but the interface cannot become an ordinary server-rendered Go page. It runs inside a sandboxed iframe and communicates with ChatGPT and Claude through the MCP Apps postMessage bridge. Browser code is still required, so a Go backend would leave this small application with two languages and two build toolchains. For WeatherSG, keeping both front end and backend in TypeScript is the simpler choice.</p><h3>Set up the project</h3><p>You will need Node.js 20 or newer, npm, Docker and a Google Cloud account if you want to follow the production section. Use a recent version of the MCP Inspector for local protocol testing.</p><p>Strictly speaking you don’t need Google Cloud, you can use any cloud provider including Azure and AWS and so on. We just need to have a server on the Internet that’s accessible by ChatGPT or Claude.</p><p>Create the project and install the packages.</p><pre>mkdir weathersg<br>cd weathersg<br>npm init -y<br><br>npm install \<br>  @modelcontextprotocol/sdk \<br>  @modelcontextprotocol/ext-apps \<br>  express leaflet react react-dom zod<br><br>npm install --save-dev \<br>  @types/express @types/leaflet @types/node \<br>  @types/react @types/react-dom \<br>  esbuild supertest tsx typescript vitest</pre><p>Set &quot;type&quot;: &quot;module&quot; in package.json, require Node.js 20 or newer, then add these scripts.</p><pre>{<br>  &quot;scripts&quot;: {<br>    &quot;build&quot;: &quot;npm run build:web &amp;&amp; tsc -p tsconfig.json&quot;,<br>    &quot;build:web&quot;: &quot;node scripts/build-web.mjs&quot;,<br>    &quot;dev&quot;: &quot;npm run build:web &amp;&amp; tsx watch src/index.ts&quot;,<br>    &quot;start&quot;: &quot;node dist/src/index.js&quot;,<br>    &quot;test&quot;: &quot;vitest run&quot;,<br>    &quot;typecheck&quot;: &quot;tsc -p tsconfig.json --noEmit&quot;<br>  },<br>  &quot;engines&quot;: {<br>    &quot;node&quot;: &quot;&gt;=20&quot;<br>  }<br>}</pre><p>Use this layout.</p><pre>weathersg/<br>  src/<br>    weather/<br>      schema.ts<br>      client.ts<br>    http-app.ts<br>    index.ts<br>    server.ts<br>  web/<br>    src/<br>      main.tsx<br>      styles.css<br>  scripts/<br>    build-web.mjs<br>  tests/<br>  Dockerfile<br>  package.json<br>  tsconfig.json</pre><p>There are two builds here. TypeScript compiles the server into dist/src. Esbuild turns the React interface into one self-contained HTML file at dist/web/weather-app.html. The server later returns that HTML as an MCP resource.</p><h3>Start with the data contract</h3><p>It is tempting to fetch an API response and pass it straight to the map. That works until the upstream response changes, a field disappears, or the model receives a different data structure from the one advertised by the tool.</p><p>Define the data crossing each boundary before writing the transport or the interface. WeatherSG calls its normalised result a WeatherSnapshot.</p><pre>import { z } from &quot;zod&quot;;<br><br>export const weatherLayerSchema = z.enum([<br>  &quot;all&quot;,<br>  &quot;forecast&quot;,<br>  &quot;rainfall&quot;,<br>]);<br><br>const forecastAreaSchema = z.object({<br>  id: z.string(),<br>  name: z.string(),<br>  latitude: z.number(),<br>  longitude: z.number(),<br>  condition: z.string(),<br>  category: z.enum([<br>    &quot;clear&quot;,<br>    &quot;cloudy&quot;,<br>    &quot;showers&quot;,<br>    &quot;thunderstorms&quot;,<br>    &quot;windy&quot;,<br>    &quot;hazy&quot;,<br>    &quot;unknown&quot;,<br>  ]),<br>});<br><br>const rainfallStationSchema = z.object({<br>  id: z.string(),<br>  name: z.string(),<br>  latitude: z.number(),<br>  longitude: z.number(),<br>  rainfallMm: z.number().nonnegative(),<br>});<br><br>export const weatherSnapshotSchema = z.object({<br>  layer: weatherLayerSchema,<br>  generatedAt: z.string(),<br>  forecast: z.object({<br>    updatedAt: z.string(),<br>    validFrom: z.string(),<br>    validTo: z.string(),<br>    validPeriodText: z.string(),<br>    areas: z.array(forecastAreaSchema),<br>  }).nullable(),<br>  rainfall: z.object({<br>    observedAt: z.string(),<br>    readingType: z.string(),<br>    unit: z.string(),<br>    stations: z.array(rainfallStationSchema),<br>  }).nullable(),<br>  summary: z.object({<br>    headline: z.string(),<br>    areasWithRain: z.number().int().nonnegative(),<br>    reportingRainStations: z.number().int().nonnegative(),<br>  }),<br>  warnings: z.array(z.string()),<br>  sources: z.array(z.object({<br>    label: z.string(),<br>    url: z.string().url(),<br>  })),<br>});<br><br>export type WeatherSnapshot = z.infer&lt;typeof weatherSnapshotSchema&gt;;</pre><p>The full project also records freshness and the wettest reporting station. Whatever fields you choose, validate data when it arrives, normalise it once, and share the output schema between the tool and the interface.</p><h3>Fetch and normalise the weather</h3><p>WeatherSG uses two official <a href="http://data.gov.sg/">data.gov.sg</a> feeds, the two-hour forecast and five-minute rainfall observations. Treat them as separate sources. One may fail while the other remains available.</p><p>The fetching helper validates every response, times out slow requests and keeps the last good value in a short cache.</p><pre>async function fetchValidated&lt;T&gt;(<br>  url: string,<br>  schema: z.ZodType&lt;T&gt;,<br>  sourceLabel: string,<br>): Promise&lt;{ value: T; warning?: string }&gt; {<br>  const cached = cache.get(url);<br><br>  try {<br>    const response = await fetch(url, {<br>      headers: { Accept: &quot;application/json&quot; },<br>      signal: AbortSignal.timeout(8_000),<br>    });<br><br>    if (!response.ok) {<br>      throw new Error(`Weather service returned HTTP ${response.status}`);<br>    }<br>    const value = schema.parse(await response.json());<br>    cache.set(url, {<br>      value,<br>      expiresAt: Date.now() + 60_000,<br>    });<br>    return { value };<br>  } catch (error) {<br>    if (cached) {<br>      return {<br>        value: cached.value as T,<br>        warning: `${sourceLabel} could not be refreshed`,<br>      };<br>    }<br>    throw error;<br>  }<br>}</pre><p>Fetch both sources together with Promise.allSettled. Do not use Promise.all here. With Promise.all, one failed feed throws away the successful result from the other feed.</p><pre>const [forecastResult, rainfallResult] = await Promise.allSettled([<br>  fetchValidated(TWO_HOUR_FORECAST_URL, forecastSchema, &quot;Forecast&quot;),<br>  fetchValidated(RAINFALL_URL, rainfallSchema, &quot;Rainfall&quot;),<br>]);</pre><p>Join the forecast labels to their coordinates, join rainfall readings to station metadata, and convert the result into WeatherSnapshot. Add warning messages when a source is missing or stale. A user should be able to tell the difference between “there is no rain” and “the rain feed is unavailable”.</p><p>Finish the function by parsing your own output.</p><pre>return weatherSnapshotSchema.parse(snapshot);</pre><p>This second validation catches mistakes in the normalisation code before they become malformed tool results.</p><h3>Register the ordinary MCP tool</h3><p>Create an McpServer in src/server.ts. Give the server instructions that explain when each tool is appropriate.</p><pre>import { McpServer } from &quot;@modelcontextprotocol/sdk/server/mcp.js&quot;;<br>import { getSingaporeWeather } from &quot;./weather/client.js&quot;;<br>import {<br>  weatherLayerSchema,<br>  weatherSnapshotSchema,<br>} from &quot;./weather/schema.js&quot;;<br><br>const server = new McpServer(<br>  { name: &quot;weathersg&quot;, version: &quot;0.1.0&quot; },<br>  {<br>    instructions:<br>      &quot;Use get_singapore_weather for factual weather questions. &quot; +<br>      &quot;Use show_singapore_weather_map when the user asks to see, &quot; +<br>      &quot;map, compare, or explore weather across Singapore.&quot;,<br>  },<br>);</pre><p>Register the text-first tool.</p><pre>server.registerTool(<br>  &quot;get_singapore_weather&quot;,<br>  {<br>    title: &quot;Get Singapore weather&quot;,<br>    description:<br>      &quot;Get current official two-hour forecasts and five-minute &quot; +<br>      &quot;rainfall observations across Singapore.&quot;,<br>    inputSchema: {<br>      layer: weatherLayerSchema.default(&quot;all&quot;),<br>    },<br>    outputSchema: weatherSnapshotSchema,<br>    annotations: {<br>      readOnlyHint: true,<br>      destructiveHint: false,<br>      openWorldHint: false,<br>    },<br>  },<br>  async ({ layer }) =&gt; {<br>    const snapshot = await getSingaporeWeather(layer);<br>    return {<br>      structuredContent: snapshot,<br>      content: [{<br>        type: &quot;text&quot;,<br>        text: `${snapshot.summary.headline} Snapshot generated at ${snapshot.generatedAt}.`,<br>      }],<br>    };<br>  },<br>);</pre><p>Return both structuredContent and content. The interface consumes the structured object. The model and hosts without UI support can still use the short text result.</p><p>Tool descriptions should say what a tool does and when it should be used. Annotations describe its safety properties. They help the host reason about approval and risk, though they are declarations rather than security controls.</p><h3>Turn the map into an MCP App</h3><p>An MCP App connects a tool to a ui:// resource. The tool returns data. The resource returns the HTML that knows how to display that data.</p><p>Import the MCP Apps server helpers and choose a versioned resource URI.</p><pre>import {<br>  registerAppResource,<br>  registerAppTool,<br>  RESOURCE_MIME_TYPE,<br>} from &quot;@modelcontextprotocol/ext-apps/server&quot;;<br><br>export const WEATHER_APP_URI =<br>  &quot;ui://weathersg/singapore-weather-map/v1.html&quot;;</pre><p>Version the URI when you make an incompatible interface change. Hosts may cache resources, and a stable URI should keep a stable meaning.</p><p>Register the map tool.</p><pre>registerAppTool(<br>  server,<br>  &quot;show_singapore_weather_map&quot;,<br>  {<br>    title: &quot;Show Singapore weather map&quot;,<br>    description:<br>      &quot;Show an interactive map of official forecasts and rainfall &quot; +<br>      &quot;observations across Singapore.&quot;,<br>    inputSchema: {<br>      layer: weatherLayerSchema.default(&quot;all&quot;),<br>    },<br>    outputSchema: weatherSnapshotSchema,<br>    annotations: {<br>      readOnlyHint: true,<br>      destructiveHint: false,<br>      openWorldHint: false,<br>    },<br>    _meta: {<br>      ui: { resourceUri: WEATHER_APP_URI },<br>      &quot;openai/toolInvocation/invoking&quot;: &quot;Reading Singapore weather…&quot;,<br>      &quot;openai/toolInvocation/invoked&quot;: &quot;Singapore weather map ready&quot;,<br>    },<br>  },<br>  async ({ layer }) =&gt; {<br>    const snapshot = await getSingaporeWeather(layer);<br>    return {<br>      structuredContent: snapshot,<br>      content: [{<br>        type: &quot;text&quot;,<br>        text: snapshot.summary.headline,<br>      }],<br>    };<br>  },<br>);</pre><p>The shared field _meta.ui.resourceUri is the important link. The two openai/toolInvocation strings improve ChatGPT&#39;s loading messages and do not replace the standard field.</p><p>Register the HTML resource next.</p><pre>registerAppResource(<br>  server,<br>  &quot;Singapore weather map&quot;,<br>  WEATHER_APP_URI,<br>  { description: &quot;Interactive map of Singapore weather&quot; },<br>  async () =&gt; ({<br>    contents: [{<br>      uri: WEATHER_APP_URI,<br>      mimeType: RESOURCE_MIME_TYPE,<br>      text: loadWeatherAppHtml(),<br>      _meta: {<br>        ui: {<br>          prefersBorder: true,<br>          csp: {<br>            connectDomains: [],<br>            resourceDomains: [&quot;https://www.onemap.gov.sg&quot;],<br>          },<br>        },<br>      },<br>    }],<br>  }),<br>);</pre><p>RESOURCE_MIME_TYPE resolves to text/html;profile=mcp-app. The content security policy is intentionally narrow. The page loads OneMap tiles, so it needs that resource domain. It does not call an API from the browser, so connectDomains stays empty.</p><p>Keep this list short. Every extra domain gives embedded code another place to send or receive data, so add only the origins the interface needs.</p><h3>Build the browser interface</h3><p>The MCP App runs in a sandboxed iframe. It does not read the parent page or the host’s cookies. Communication goes through the MCP Apps bridge over postMessage.</p><p>Create the app and connect it to the host.</p><pre>import { App } from &quot;@modelcontextprotocol/ext-apps&quot;;<br>import { createRoot } from &quot;react-dom/client&quot;;<br><br>const app = new App(<br>  { name: &quot;WeatherSG map&quot;, version: &quot;0.1.0&quot; },<br>  {},<br>  { autoResize: true },<br>);<br><br>function parseSnapshot(value: unknown): WeatherSnapshot | null {<br>  if (!value || typeof value !== &quot;object&quot;) return null;<br>  const candidate = value as Partial&lt;WeatherSnapshot&gt;;<br>  if (!candidate.summary || !Array.isArray(candidate.sources)) return null;<br>  if (!candidate.forecast &amp;&amp; !candidate.rainfall) return null;<br>  return candidate as WeatherSnapshot;<br>}<br><br>app.ontoolresult = (result) =&gt; {<br>  const snapshot = parseSnapshot(result.structuredContent);<br>  if (snapshot) deliverSnapshot(snapshot);<br>};<br><br>createRoot(document.getElementById(&quot;root&quot;)!).render(&lt;WeatherApp /&gt;);<br><br>void app.connect().catch((error) =&gt; {<br>  console.error(&quot;Unable to connect to the host&quot;, error);<br>});</pre><p>Callback names may change as the extension develops, so check the current <a href="https://apps.extensions.modelcontextprotocol.io/api/">MCP Apps API reference</a> against the package version in your lockfile. The architecture remains the same. Check incoming structured content before rendering it. The server has already applied the full Zod schema, while the browser rejects any result missing fields the interface needs.</p><p>The React component can now treat the result like ordinary application data. WeatherSG uses Leaflet with OneMap tiles, forecast markers and rainfall station markers. Layer buttons switch between the forecast and rainfall already present in the snapshot, so they do not make another network request.</p><p>Do not let the component fetch privileged data directly if the server can do it. Keeping data access behind MCP tools gives you one place for validation, authentication, logging, caching and error handling.</p><h3>Bundle the interface as one HTML resource</h3><p>An MCP resource is easier to serve when its scripts and styles are inlined. WeatherSG uses esbuild to bundle React, then injects the JavaScript and CSS into a small HTML shell.</p><p>The resulting file should contain everything except explicitly allowed network resources such as map tiles.</p><pre>await build({<br>  entryPoints: [&quot;web/src/main.tsx&quot;],<br>  bundle: true,<br>  minify: true,<br>  format: &quot;esm&quot;,<br>  platform: &quot;browser&quot;,<br>  write: false,<br>  outdir: &quot;dist/web-bundle&quot;,<br>});</pre><p>After building, read the generated JavaScript and CSS, insert them into script and style elements, then write dist/web/weather-app.html. The complete project does this in scripts/build-web.mjs.</p><p>Run the build before moving on.</p><pre>npm run build</pre><p>Open the generated HTML and check that it contains no references to local development paths. The iframe will not be able to load localhost, your source tree or a Vite development server once it is running inside a remote host.</p><h3>Serve MCP over Streamable HTTP</h3><p>ChatGPT and Claude need a public HTTPS endpoint. Use Streamable HTTP at /mcp.</p><pre>import { createMcpExpressApp } from<br>  &quot;@modelcontextprotocol/sdk/server/express.js&quot;;<br>import { StreamableHTTPServerTransport } from<br>  &quot;@modelcontextprotocol/sdk/server/streamableHttp.js&quot;;<br>import { createWeatherMcpServer } from &quot;./server.js&quot;;<br><br>const app = createMcpExpressApp();<br><br>app.post(&quot;/mcp&quot;, async (request, response) =&gt; {<br>  response.setHeader(&quot;Cache-Control&quot;, &quot;no-store&quot;);<br><br>  const server = createWeatherMcpServer();<br>  const transport = new StreamableHTTPServerTransport({<br>    sessionIdGenerator: undefined,<br>  });<br><br>  await server.connect(transport);<br><br>  response.on(&quot;close&quot;, () =&gt; {<br>    void transport.close();<br>    void server.close();<br>  });<br><br>  await transport.handleRequest(request, response, request.body);<br>});</pre><p>This example creates a stateless transport for every POST request. That suits two read-only tools with no server-side session. If your application maintains subscriptions or long-lived state, choose and test a session strategy instead of copying this pattern blindly.</p><p>Add health and readiness endpoints.</p><pre>app.get(&quot;/health&quot;, (_request, response) =&gt; {<br>  response.json({ status: &quot;ok&quot;, service: &quot;weathersg&quot; });<br>});<br><br>app.get(&quot;/ready&quot;, (_request, response) =&gt; {<br>  const ready = existsSync(&quot;dist/web/weather-app.html&quot;);<br>  response.status(ready ? 200 : 503).json({<br>    status: ready ? &quot;ready&quot; : &quot;not_ready&quot;,<br>  });<br>});</pre><p>/health says that the process is alive. /ready says that it can serve the app. They answer different operational questions.</p><p>Read the port from the environment in src/index.ts.</p><pre>const port = Number(process.env.PORT ?? 3000);<br>const app = createWeatherHttpApp();<br><br>app.listen(port, &quot;0.0.0.0&quot;, () =&gt; {<br>  console.log(`WeatherSG listening on ${port}`);<br>});</pre><h3>Test the protocol before the chat interface</h3><p>Start locally.</p><pre>npm run dev</pre><p>Then open the MCP Inspector.</p><pre>npx @modelcontextprotocol/inspector@latest</pre><p>Connect it to http://localhost:3000/mcp with Streamable HTTP. Check these items in order.</p><ol><li>The server initialises without an error.</li><li>Both tools appear with their input and output schemas.</li><li>get_singapore_weather returns text and structured content.</li><li>show_singapore_weather_map advertises the ui:// resource.</li><li>The resource has the MIME type text/html;profile=mcp-app.</li><li>All three layer inputs work.</li><li>A bad layer fails validation.</li></ol><p>Test the browser interface through the MCP Apps basic host as well.</p><pre>git clone https://github.com/modelcontextprotocol/ext-apps.git<br>cd ext-apps/examples/basic-host<br>npm install<br>SERVERS=&#39;[&quot;http://localhost:3000/mcp&quot;]&#39; npm start</pre><p>Open http://localhost:8080, select the map tool and call it. This separates interface faults from model tool-selection faults. Debugging both at once is needlessly confusing.</p><p>Run the automated checks before every deployment.</p><pre>npm run typecheck<br>npm test<br>npm run build</pre><p>The WeatherSG repository tests schema handling, partial upstream failures, MCP metadata, HTTP routes and the generated HTML bundle. The current suite contains 16 tests.</p><h3>Put the server in a container</h3><p>Use a two-stage image so compilers and source files do not end up in the runtime image.</p><pre>FROM node:22-alpine AS build<br>WORKDIR /app<br>COPY package.json package-lock.json ./<br>RUN npm ci<br>COPY . .<br>RUN npm run build<br><br>FROM node:22-alpine AS runtime<br>WORKDIR /app<br>ENV NODE_ENV=production<br>COPY package.json package-lock.json ./<br>RUN npm ci --omit=dev<br>COPY --from=build /app/dist ./dist<br>EXPOSE 3000<br>HEALTHCHECK --interval=30s --timeout=5s \<br>  CMD [&quot;node&quot;, &quot;-e&quot;, &quot;fetch(&#39;http://127.0.0.1:&#39;+(process.env.PORT||3000)+&#39;/ready&#39;).then(r=&gt;{if(!r.ok)process.exit(1)}).catch(()=&gt;process.exit(1))&quot;]<br>CMD [&quot;node&quot;, &quot;dist/src/index.js&quot;]</pre><p>Build and run it locally.</p><pre>docker build -t weathersg .<br>docker run --rm -p 3000:3000 weathersg</pre><p>Check http://localhost:3000/health and run the Inspector against the container. This catches missing build artefacts and paths that only worked on your development machine.</p><h3>Deploy to Google Cloud Run</h3><p>Cloud Run is a convenient fit because it gives the container a public HTTPS address and supplies the PORT environment variable. You can of course use just plain old VM instances on any platform like Azure or AWS. Google Cloud Run is just the tool I found available to me.</p><p>These commands create billable cloud resources, so check the active project before running them.</p><pre>gcloud auth login<br>gcloud config set project YOUR_PROJECT_ID<br>gcloud services enable \<br>  run.googleapis.com \<br>  cloudbuild.googleapis.com \<br>  artifactregistry.googleapis.com</pre><p>Deploy from the project directory.</p><pre>gcloud run deploy weathersg \<br>  --source . \<br>  --region asia-southeast1 \<br>  --allow-unauthenticated \<br>  --set-env-vars PUBLISHER_NAME=WeatherSG</pre><p>Cloud Run prints a service URL when the deployment finishes. Your MCP endpoint is that URL with /mcp appended.</p><pre>https://YOUR_SERVICE_HOST/mcp</pre><p>For a public read-only weather service, unauthenticated access is reasonable. An app that reads private data or performs actions needs authentication and authorisation before you expose it. Public HTTPS is transport security, not user identity.</p><p>Use a custom domain before public directory submission if you want a stable publisher origin. WeatherSG uses <a href="https://weathersg.sausheong.dev/mcp.">https://weathersg.sausheong.dev/mcp.</a></p><p>Verify the deployed service from outside the container.</p><pre>curl -fsS https://YOUR_SERVICE_HOST/health<br>curl -fsS https://YOUR_SERVICE_HOST/ready</pre><p>Then connect MCP Inspector to the production /mcp URL and repeat the tool and resource checks. During the verification for this article, the WeatherSG production endpoint returned both tools, the MCP App resource and current government weather data without warnings.</p><h3>Add WeatherSG to ChatGPT</h3><p>OpenAI’s current documentation still requires Developer mode for testing an unpublished MCP server. Open ChatGPT settings, choose <strong>Security and login</strong>, then enable <strong>Developer mode</strong>. Availability may depend on your account and workspace policy.</p><p>Go to <a href="https://chatgpt.com/plugins">ChatGPT Plugins</a> and select <strong>Create app</strong> or the plus button. The form currently opens as <strong>New Plugin</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fW84Sq8vEa9v_jbc-RvjGg.jpeg" /></figure><p>Fill it in as follows.</p><ul><li>For <strong>Name</strong>, enter WeatherSG.</li><li>For <strong>Description</strong>, enter Interactive Singapore forecasts and rainfall map.</li><li>For <strong>Connection</strong>, choose Server URL.</li><li>For <strong>MCP Server URL</strong>, enter <a href="https://YOUR_SERVICE_HOST/mcp.">https://YOUR_SERVICE_HOST/mcp.</a></li><li>For <strong>Authentication</strong>, choose No Auth for this public read-only example.</li></ul><p>The placeholder in the form may end in /sse. WeatherSG uses Streamable HTTP, so enter the complete /mcp URL. Tick the acknowledgement only after checking that the server is yours and that the discovered tools match what you deployed.</p><p>Create the connection, review both tools, then start a new conversation and enable WeatherSG from the tools menu. Try these prompts.</p><pre>Is it raining anywhere in Singapore right now?<br><br>Show me the Singapore weather map.<br><br>Now show only rainfall stations.</pre><p>The first prompt should favour the factual tool. The second should open the map. The follow-up should call the map tool again with layer set to rainfall.</p><p>This is the completed map inside ChatGPT.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CAB7-iVkEuWfhSvh0gB66g.jpeg" /></figure><p>OpenAI’s <a href="https://developers.openai.com/plugins/deploy/connect-chatgpt">connection and testing guide</a> is the source of truth when these labels move.</p><h3>Add WeatherSG to Claude</h3><p>Claude calls remote MCP servers custom connectors. For an individual account, open <strong>Customize</strong>, choose <strong>Connectors</strong>, select the plus button, then choose <strong>Add custom connector</strong>. Team and Enterprise organisations require an owner to add the connector under the organisation’s connector settings before members can connect it.</p><p>The official MCP Apps guide shows the connector form below. Its surrounding Claude navigation may differ from the current interface, though the name and remote URL fields remain the same.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xVTDr_9tqbAgdn-EbBMISg.jpeg" /><figcaption><em>Screenshot from the </em><a href="https://modelcontextprotocol.io/extensions/apps/build"><em>official MCP Apps build guide</em></a><em>.</em></figcaption></figure><p>Enter WeatherSG as the name and the complete production URL as the remote MCP server URL.</p><pre>https://YOUR_SERVICE_HOST/mcp</pre><p>WeatherSG does not use OAuth, so leave the advanced OAuth fields empty. Select <strong>Add</strong>, start a new conversation, open the plus menu, choose <strong>Connectors</strong>, and enable WeatherSG for that conversation.</p><p>Ask Claude to show the Singapore weather map. Claude on the web and Claude Desktop support MCP Apps, so the same ui:// resource can render inline or in a larger view. The connection originates from Anthropic&#39;s cloud infrastructure even when you use Claude Desktop. A server reachable only on your laptop therefore needs a public development tunnel or the separate local MCP configuration.</p><p>Anthropic’s <a href="https://support.claude.com/en/articles/11175166-get-started-with-custom-connectors-using-remote-mcp">remote custom connector guide</a> records the latest plan and organisation rules.</p><h3>You now have a working MCP App</h3><p>You have now taken WeatherSG through the complete path from an external API to an MCP tool, an embedded interface, a container and a public deployment. The same /mcp endpoint works in ChatGPT and Claude because the server describes the tool and interface through the shared MCP Apps protocol.</p><p>Run the typecheck, tests, production build and deployment verifier once more before tagging a release. Keep those commands in the release process so later changes to the weather adapter, tool metadata or interface do not break the deployed application without warning.</p><p>From here, add one capability at a time. Station search, saved map views and authenticated rain alerts are natural extensions. Begin each one with its data contract and permission model, then carry it through the tool, resource, interface and deployment checks you have already built.</p><p>An MCP App is a web application whose front door is a conversation. The model chooses the tool, the host contains the interface, and your server remains responsible for the data and permissions. WeatherSG keeps those responsibilities small enough to inspect, making it a useful first MCP App.</p><h3>Further reading</h3><ul><li><a href="https://modelcontextprotocol.io/extensions/apps/overview">MCP Apps overview</a></li><li><a href="https://modelcontextprotocol.io/extensions/apps/build">Build an MCP App</a></li><li><a href="https://apps.extensions.modelcontextprotocol.io/api/">MCP Apps API reference</a></li><li><a href="https://developers.openai.com/plugins/build/chatgpt-ui">OpenAI guide to adding UI to an MCP server</a></li><li><a href="https://developers.openai.com/plugins/deploy/connect-chatgpt">OpenAI guide to connecting and testing a plugin</a></li><li><a href="https://support.claude.com/en/articles/11175166-get-started-with-custom-connectors-using-remote-mcp">Anthropic guide to remote custom connectors</a></li><li><a href="https://api-open.data.gov.sg/v2/real-time/api/two-hr-forecast">Singapore two-hour forecast API</a></li><li><a href="https://api-open.data.gov.sg/v2/real-time/api/rainfall">Singapore rainfall API</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c07ee1d17191" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How Do You Watermark a Paragraph?]]></title>
            <link>https://medium.com/@sausheong/how-do-you-watermark-a-paragraph-b10712c2a347?source=rss-a358058b2410------2</link>
            <guid isPermaLink="false">https://medium.com/p/b10712c2a347</guid>
            <category><![CDATA[llm]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[ai-watermarking]]></category>
            <category><![CDATA[anthropic-claude]]></category>
            <dc:creator><![CDATA[Sau Sheong]]></dc:creator>
            <pubDate>Tue, 01 Sep 2026 03:15:47 GMT</pubDate>
            <atom:updated>2026-09-01T03:15:47.312Z</atom:updated>
            <content:encoded><![CDATA[<h4>How AI text watermarking works, and what it can and cannot prove</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6Sv7GKvATfwsPo1p-TfeHA.jpeg" /><figcaption>generated by Gemini 3.6 Flash</figcaption></figure><p>Anthropic recently announced that it is going to start watermarking text generated by Claude. My first thought was probably the same as yours.</p><p>What exactly does it mean to watermark text?</p><p>With an image, it is easy to imagine. You can hide information in pixels, attach metadata or put a barely visible logo across the picture. A banknote has faint patterns that are difficult to reproduce. A stock photograph has a translucent name across the middle.</p><p>But text?</p><p>If I copy a paragraph from Claude and paste it into a plain text editor, there is nothing left except the words. I can change the font, send it through WhatsApp, publish it on a blog, print it and type it back into another computer. All the original formatting and metadata are gone.</p><p>And yet the watermark may still be detectable.</p><p>There is no hidden phrase saying MADE BY CLAUDE. There are no invisible Unicode characters. There is no secret account number tucked into the document.</p><p>So where is the watermark?</p><p>It turns out that it is hidden in the choices Claude made while writing.</p><p>In August 2026, Anthropic confirmed that future Claude models would generate watermarked text. Around 190 signatories, including most of the major model providers, had signed the European Union’s <a href="https://digital-strategy.ec.europa.eu/en/policies/code-practice-ai-generated-content">Code of Practice on Transparency of AI-Generated Content</a> in July. The <a href="https://digital-strategy.ec.europa.eu/en/faqs/transparency-obligations-under-article-50-ai-act">obligation to mark AI-generated content</a> took effect on 2 August. Anthropic followed with a <a href="https://www.anthropic.com/news/claude-text-watermark">technical explainer</a> on 14 August and disclosed that Claude’s watermark is a version of SynthID-Text, the method Google DeepMind <a href="https://www.nature.com/articles/s41586-024-08025-4">published in <em>Nature</em> in 2024</a>.</p><p>The mechanism is rather clever, but the idea behind it is not new. People have been trying to hide information in text for a long time.</p><h3>Where can you hide something in text?</h3><p><a href="https://tnlandforms.us/cns05/brassil95electronic.pdf">Researchers in the 1990s</a> treated a document rather like a picture. If a page is an image, you can encode information in its geometry. Move one line a fraction of a millimetre up or down, widen the gap between two words by an imperceptible amount or alter the shape of a character very slightly.</p><p>Suppose normal word spacing means 0 and slightly wider spacing means 1. A page can then carry a binary string without changing a single word.</p><pre>1 0 1 1 0 1 0 0 1 ...</pre><p>These techniques had wonderfully literal names such as line-shift coding, word-shift coding and feature coding. They worked well enough for tracking leaked documents. Give every recipient a copy with a different spacing pattern and a leaked photocopy can identify the recipient.</p><p>The weakness becomes obvious as soon as you stop thinking about the page and start thinking about the words. Copy the text into another word processor and the watermark disappears. Reflow it, change the font, run it through OCR or print and rescan it, and most of the signal goes with the formatting.</p><p>The watermark belonged to the page formatting, not the text.</p><p><a href="https://www.unicode.org/versions/Unicode17.0.0/core-spec/chapter-6/">Unicode</a> offered another hiding place. It contains characters that occupy no visible space, including zero-width spaces and zero-width joiners. One invisible character can represent 0 and another can represent 1.</p><p>A reader sees this.</p><pre>The cat sat on the mat.</pre><p>Software examining the underlying code points sees something closer to this.</p><pre>The&lt;ZWSP&gt; cat&lt;ZWNJ&gt; sat&lt;ZWSP&gt; on the mat.</pre><p>Other versions use different kinds of spaces, alternative quotation marks, capitalisation, optional punctuation or characters that look alike on screen but have different Unicode values. These methods can carry quite a lot of information, enough for a document identifier, customer number, timestamp or even a short message.</p><p>They are also very easy to destroy. Normalise the Unicode or strip non-printing characters and the watermark vanishes. Pasting the text into a plain text field, saving it as ASCII or putting it through a content management system may be enough.</p><p>This was one of the more common reactions to Anthropic’s announcement. People assumed Claude was inserting invisible characters, and a small industry of online “watermark removers” appeared to strip them out. Those tools may remove zero-width characters. They do not remove the watermark Anthropic described.</p><p><a href="https://doi.org/10.1145/3691626">Researchers eventually moved the watermark into the language itself</a>. The simplest approach was synonym substitution. You agree that certain word choices represent certain bits.</p><pre>big      = 0        large  = 1<br>quick    = 0        rapid  = 1<br>perhaps  = 0        maybe  = 1</pre><p>Grammar can carry bits too.</p><pre>John gave Mary the book.             -&gt; 0<br>The book was given to Mary by John.  -&gt; 1</pre><p>Now copying and reformatting the text changes nothing because the watermark is part of the writing. Unfortunately, the writing may also get worse.</p><p>Synonyms are rarely perfect substitutes. “Big” and “large” do not always sound the same. An active sentence and a passive one place emphasis differently. Change enough words and sentence structures to encode information and you may alter the meaning, the tone or simply the quality of the prose.</p><p>This was the problem linguistic watermarking could never quite escape. You need to change the text enough to leave a signal, but not so much that a reader notices the machinery.</p><p>Then large language models arrived with thousands of choices already built in.</p><h3>A language model is a very large bag of dice</h3><p>A language model does not normally plan a complete paragraph and then fill in the words. It generates one token at a time. A token is roughly a word or part of a word, though the exact boundaries depend on the model.</p><p>Consider this unfinished sentence.</p><pre>The weather today was cold and</pre><p>The model calculates a probability for every possible next token. The numbers might look something like this.</p><pre>overcast     30%<br>grey         25%<br>damp         20%<br>miserable    10%<br>windy         8%<br>...<br>sugary        0.00001%</pre><p>The exact figures are made up. Look instead at the shape of the distribution. “Sugary” is wildly implausible. Several other choices are perfectly reasonable. A reader would not care whether the sentence ended with “overcast” or “grey” and the meaning would be much the same.</p><p>In mathematical terms, the model has a probability distribution for the next token.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AKs80tbrFEQBEOGthiwmcw.png" /></figure><p>That means, given everything generated so far, what is the probability of each possible next token?</p><p>The model samples from that distribution, adds the chosen token to the text and does the whole calculation again. A thousand-word article may involve around fifteen hundred such decisions.</p><p>That creates an unusual opportunity. Instead of adding a watermark after the text has been written, you can hide one in the randomness used to write it.</p><p>Imagine flipping a fair coin a few thousand times. You expect roughly half heads and half tails, in no particular order.</p><p>Now suppose I do not flip a coin. I use a secret cryptographic key to generate a very long sequence of pseudorandom bits and read from that sequence instead.</p><p>To you, nothing seems to have changed. A good pseudorandom sequence looks random. Heads still appears about half the time and tails the other half. But I have the key, so I can recreate the same sequence whenever I want. If you give me a record of coin flips and it matches my secret sequence far better than chance would allow, I have statistical evidence that it came from my process.</p><p><a href="https://www.anthropic.com/news/claude-text-watermark">Anthropic explains the idea with a game of Monopoly</a>. Instead of rolling dice, the players take their moves from the digits of pi, beginning at some arbitrary point deep in the expansion. The game still looks normal. Nobody at the table can predict the next move and the outcome is not biased towards any player. Afterwards, someone who knows the starting point can recognise that the game followed pi. In that sense, the game carries a watermark.</p><p>Replace coin flips or Monopoly moves with tokens. The model is choosing among “large”, “substantial”, “considerable” and “significant”. A secret key influences the source of randomness behind those otherwise acceptable choices.</p><p>One token proves nothing. Hundreds or thousands of choices correlated with the same key create a signal that is unlikely to appear by accident.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Ywe6kct3elqDaLS9TRn9LA.png" /></figure><p>There is no single marker anywhere in the document. The pattern is the marker.</p><h3>Green words and red words</h3><p><a href="https://proceedings.mlr.press/v202/kirchenbauer23a.html">John Kirchenbauer and his colleagues published</a> one of the most influential modern LLM watermarking techniques in 2023. It is easier to understand than the name might suggest.</p><p>At each token position, use a secret key and the preceding text to divide the model’s vocabulary pseudorandomly into two groups. Call one group green and the other red. Then give the green tokens a small probability boost.</p><p>Return to the weather sentence.</p><pre>overcast     30%<br>grey         25%<br>damp         20%<br>miserable    10%</pre><p>At this particular position, the watermark may decide that “grey” and “miserable” are green. Their probabilities increase a little. The model is not forced to choose either word and “overcast” can still win. A green token is simply more likely.</p><p>The context changes after each generated token, so a different green list is created for the next position, then another for the position after that.</p><p>Detection is a counting exercise. Ordinary text should happen to use green tokens about as often as the random split predicts. Watermarked text should use them more often. A detector holding the secret key can reconstruct the green list at every position and count how many generated tokens landed in it.</p><p>The usual simplified score is this.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iUN5OQViWYmTbrQeU1UkkA.png" /></figure><p>Here, <em>NG</em>​ is the number of observed green tokens, <em>T</em> is the number of tokens and <em>γ</em> is the expected fraction of the vocabulary placed on the green list.</p><p>You do not need the equation to follow the idea. Flip a coin twenty times and fourteen heads is mildly interesting. Flip it ten thousand times and get seven thousand heads and something unusual is happening. More observations make a small bias easier to see.</p><p>The trouble is that a green-list watermark changes the model’s original distribution. Suppose the model gives the best word a probability of 60 per cent, a reasonable alternative 30 per cent and a poor one 10 per cent. If the watermark favours the poor word, it pushes the model towards a choice the model itself rated lower.</p><p>You can describe the change to a token’s logit, its pre-sampling score, like this.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yzeZ_sM5WBVU9fn2HSW6ew.png" /></figure><p>The value δ is the boost given to green tokens. A larger boost creates a stronger, easier-to-detect watermark. It also interferes more with what the model would otherwise have written.</p><p>For a company selling a frontier model, that is an awkward bargain. Even a small systematic drop in answer quality would damage the product. If watermarking made Claude noticeably worse, it would be a difficult feature to defend, regulatory obligation or not.</p><p>So researchers asked a harder question. Could the model keep exactly the same probabilities while the random choices still carried a secret correlation?</p><p>This is where SynthID comes in.</p><h3>A tournament where the odds stay the same</h3><p>Google DeepMind developed SynthID as a family of provenance technologies and published the text version in <em>Nature</em> in 2024. Anthropic says Claude uses a version of this approach. The line of ideas reaches back to <a href="https://scottaaronson.blog/?p=6823">a proposal Scott Aaronson made in 2022</a>.</p><p>One of SynthID-Text’s mechanisms is called <em>tournament sampling</em>. The name sounds more elaborate than the basic idea. When the model needs its next token, it runs a small, secret knockout competition among several possible choices.</p><p>Suppose the model is completing the phrase “The sky was…” and gives <em>cloudy</em> a probability of 50 per cent, <em>grey</em> 30 per cent and <em>damp</em> 20 per cent. Tournament sampling starts by drawing candidates using those probabilities. It does not put each word into the competition once. A likely word such as <em>cloudy</em> is more likely to be drawn, and may appear several times. A less likely word can still appear, just less often.</p><pre>cloudy    grey    cloudy    damp<br>grey      cloudy  damp      cloudy</pre><p>The candidates are paired. A secret scoring function gives each candidate a pseudorandom score, usually a zero or a one. The score is calculated from the watermark key and the few tokens that came before it. The higher-scoring candidate in each pair advances. If both have the same score, the winner is chosen at random. The winners are paired again and the process continues until one token remains.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*peaq0SGKqXUMTBrgJrCOIw.png" /></figure><p>The diagram shows three levels, so it begins with eight candidates. More generally, <em>m</em> levels correspond to 2<em>m</em> candidates in this conceptual tournament. Each level uses a different keyed scoring function. For a candidate token <em>x</em> and a context-derived random value <em>rt</em>​, those functions can be written as</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*24UMXk6F5Kw9okQdIm2OCw.png" /></figure><p>This bracket is a way to understand the algorithm, not necessarily how it is executed in software. DeepMind’s experiments commonly used 30 levels, and constructing 230230 candidates for every token would plainly be impractical. The <a href="https://github.com/google-deepmind/synthid-text">published implementation</a> calculates the equivalent changes to the token probabilities one level at a time. It gets the same sampling effect without building a billion-entry tournament.</p><p>Why does any of this leave a watermark? For one particular context, the key favours some candidates over others. Across a long passage, the selected tokens therefore score a little better against the secret functions than chance would predict. A reader sees ordinary prose. A detector with the key can reconstruct the scores and look for that accumulated statistical lean. One winning token proves nothing. Hundreds of choices can provide evidence.</p><p>There is still an obvious question. If the scoring functions favour particular tokens, has SynthID simply disguised the same distortion created by a green list?</p><p>For a fixed context and key, the probabilities do shift. If <em>grey</em> receives the higher secret score in this round, it gets an advantage. The non-distortion claim is about what happens when those pseudorandom scores are averaged over. A token is favoured in some contexts and not in others. With two candidates in each match, its average probability returns to the probability assigned by the original model. <em>Cloudy</em> remains a 50 per cent choice overall, <em>grey</em> a 30 per cent choice and <em>damp</em> a 20 per cent choice. The key influences which particular sequence is produced without creating a systematic preference for one word.</p><p>Think about the coin again. A secret pseudorandom sequence can determine individual flips while heads still appears half the time across many flips. The coin has not acquired a bias towards heads. Its particular sequence has acquired a pattern that someone with the key can test for.</p><p>DeepMind calls the basic property <em>single-token non-distortion</em>. It also uses repeated-context masking so that the non-distortion property extends across a generated passage. In its experiments, it configured SynthID-Text to be single-sequence non-distortionary. This is the version intended to preserve output quality, although a stronger distortionary configuration is also possible when detectability matters more.</p><p>There is a nuance. Preserving the distribution within an individual response does not necessarily preserve all response-to-response diversity because outputs can become correlated with the watermark’s pseudorandom process. DeepMind notes this distinction. Anthropic’s public explanation understandably spends less time on it.</p><p>The quality evidence goes beyond a vendor saying that everything is fine. <a href="https://www.nature.com/articles/s41586-024-08025-4">DeepMind ran a live experiment</a> that served watermarked responses to part of Gemini’s traffic, covering close to twenty million responses, and compared thumbs-up and thumbs-down ratings with the unwatermarked model. It found no statistically significant difference. Human raters in a separate controlled study could not distinguish the two on quality. Anthropic says its internal tests likewise found no effect on content, creativity or readability.</p><p>That is a good example of research turning into infrastructure. The watermark can be detectable to the holder of the key without making a user reach for the dictionary because Claude suddenly decided that “nubilous” was a better word than “overcast”.</p><h3>How the detector finds the pattern</h3><p>Detection does not rerun the tournament or try to reconstruct the candidates that lost. It recreates only the scoring side of the process. To do that, it needs the text, the same tokenizer and the secret watermark key. It does not search a database of Claude conversations, and it does not ask another language model whether the writing sounds artificial.</p><p>Take the sentence “The sky was grey and heavy.” The detector first splits it into the same tokens used during generation. At the position occupied by <em>grey</em>, it takes the preceding tokens, combines them with the secret key and reconstructs the pseudorandom value used for that position. From this, it can calculate the same scores that <em>grey</em> would have received at every tournament level.</p><p>Suppose there are three levels and <em>grey</em> receives the scores 1, 1 and 0. It has scored two out of three. The detector then moves to <em>and</em>, uses the new preceding context to reconstruct that token’s scores, and repeats the calculation for <em>heavy</em>, the full stop and every other usable token in the passage.</p><p>If the text was written without the watermark, zeros and ones should occur at roughly the rate expected by chance. A watermarked sampler, however, repeatedly gives higher-scoring candidates a better chance of surviving. Its selected tokens should therefore collect slightly more ones. <a href="https://www.nature.com/articles/s41586-024-08025-4">SynthID’s simplest detection score</a> is the average of those values across all T<em>T</em> tokens and all m<em>m</em> tournament levels.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/976/1*FgWTCdKrzSz_nkLasfXNiA.png" /></figure><p>Here is a deliberately simplified example. A passage of 100 tokens scored across three tournament levels produces 300 zeros and ones. Unwatermarked text might produce about 150 ones. If the observed text produces 180, the detector asks how often an unwatermarked passage would reach a score that high by chance. The actual calculation is calibrated more carefully, but that is the statistical question being asked.</p><p>The watermark is not hiding in any particular word. <em>Grey</em> might receive a high score in one context and a low score in another. The evidence lies in the small excess that accumulates across the passage. One token scoring two out of three means very little. A long sequence scoring higher than ordinary text becomes progressively harder to explain as chance.</p><p>The detector must then decide how unusual the final score is. One approach compares it with the scores expected from unwatermarked text. Another uses a Bayesian model to compare two possibilities.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/792/1*cCRK8u8M9W1MyJc5iryueA.png" /></figure><p>The first asks how likely the observed score <em>S</em> would be if the text were watermarked. The second asks how likely it would be if the text were not. Combining those distributions with the detector’s prior assumptions produces an estimate such as</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/531/1*p6sL0w8syDZEmlTQIYVOkQ.png" /></figure><p>the probability assigned to the watermarked explanation after seeing the score. <a href="https://github.com/google-deepmind/synthid-text">SynthID’s reference implementation</a> provides mean, weighted-mean, frequentist and Bayesian detectors. Its Bayesian detector is trained for a particular watermark key and can return an uncertain result instead of forcing every passage into yes or no.</p><p>Any detector still needs a decision threshold. Set the threshold high and it will make fewer false accusations, but it will also miss more watermarked text. Set it lower and it will find more watermarks while increasing false positives. The appropriate setting depends on whether the result is being used as a weak moderation signal or as evidence in a consequential decision.</p><p>Length and freedom of choice matter here for the same reason they matter during generation. A long, varied passage gives the detector many small observations to combine. A short answer, a quotation or a tightly constrained piece of code may provide too little evidence for a confident result. Detection is therefore a statistical judgement about a passage, not the reading of a hidden label stamped onto every sentence.</p><h3>What Anthropic has actually committed to</h3><p>The public reaction often ran ahead of the announcement, so the boundaries are useful.</p><p>Anthropic says the watermark applies to text generated by Claude models launched after 2 August 2026. Older models are covered by a transition period in the EU law, and the company says it is working to add watermarking to them over the following months.</p><p>It applies globally rather than only to users in Europe. Anthropic says it does not yet have a durable way to limit the behaviour by region and will continue evaluating that decision.</p><p>The watermark carries no identifying information. It does not encode your account, organisation or conversation identifier. Nothing in the watermark or the key can be used to recover who prompted Claude. The signal concerns the generation system, not the user.</p><p>It does not add tokens, so there is no additional token charge. Anthropic also says the speed cost is negligible.</p><p>A detection API is planned, although its details were still being worked out when Anthropic made the announcement. The secret key is fundamental to detection, so this is likely to be a service rather than a key published for anyone to download. Publishing the key would make independent detection easier, but it could also help attackers reproduce or spoof the signal.</p><p>Files use a different mechanism. When Claude creates an image or a similar file, Anthropic attaches a <a href="https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html">C2PA content credential</a>. This is a cryptographically signed record in the file’s metadata saying that Claude created or processed it. C2PA is an open industry standard also used by camera makers and photo-editing software.</p><p>A C2PA credential is not the text watermark described here. It is a label attached to a file and can be lost when someone re-saves the file, converts its format, takes a screenshot or uploads it to a service that rewrites metadata. The text watermark is more interesting because it survives the loss of the original container.</p><p>Anthropic has not disclosed its production keys or parameters, which is hardly surprising. It has disclosed enough of the architecture for us to reason about what the system can and cannot do.</p><h3>Some text gives the watermark more room</h3><p>A watermark like this needs choices. If there is only one correct continuation, there is nowhere to hide a signal.</p><p>Ask Claude what two plus two is and the answer must be four. A watermark that steers the model towards five has failed in a more basic way than watermarking. Anthropic gives another example. Complete “Isaac Newton’s most famous work was called <em>Principia</em>…” and the next word has to be <em>Mathematica</em>. There is no equally good substitute.</p><p>Now ask Claude for an atmospheric description of Paris at dawn. The model has plenty of room. Almost every sentence can be written several reasonable ways.</p><p>Information theory calls this uncertainty entropy. For a model’s next-token probabilities <em>pi</em>​, it is commonly expressed as</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9LgY1G1-MaADvyO9ewak_g.png" /></figure><p>When <em>Ht</em>​ is close to zero, the model is nearly certain about the next token and the watermark has little capacity. When entropy is high, several tokens are plausible and there are more choices in which to hide the signal. Anthropic says its watermark is not applied where there is effectively only one correct choice. That is functionally entropy-sensitive behaviour, although the company has not disclosed whether its implementation uses any particular published entropy-adaptive algorithm.</p><p>This explains why code is difficult.</p><pre>if err != nil {<br>    return err<br>}</pre><p>There are few meaningful alternatives to this Go fragment. Replacing a token to strengthen a watermark may produce a bug rather than a stylistic variation.</p><p>Prose is much more accommodating.</p><pre>The results suggest...<br>The results indicate...<br>The results show...<br>The results imply...</pre><p>All four may work, and each choice can carry a little evidence. Watermark capacity is therefore related to the acceptable uncertainty across generation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cQPewEWzi9W_-n741rVo5g.png" /></figure><p>That is an intuition rather than Anthropic’s production formula. It captures why creative prose offers plenty of capacity while constrained code does not. Comments, names and formatting choices provide some room, but the executable parts of code provide much less. Anthropic acknowledges this. If you hoped a detector could reliably identify every Claude-generated pull request, this mechanism will disappoint you.</p><p>Editing sits on an interesting boundary. Write a sentence yourself and ask Claude to fix the punctuation. Claude may change three tokens. Three choices do not provide enough evidence for a detector.</p><p>Give Claude a five-word prompt and ask for a two-thousand-word essay, and it makes thousands of choices. The signal should be much stronger.</p><p>This distinction is easy to miss. A positive result means Claude probably generated a material portion of the detected tokens. It does not tell you who came up with the ideas.</p><p>If I write an essay and Claude fixes my commas, the intellectual work is mine and the watermark may be absent. If I give Claude a prompt and publish its complete response, the watermark may be strong while my intellectual contribution is small. Most real uses sit somewhere between those examples. The detector cannot separate “Claude wrote this” from “Claude heavily rewrote this”.</p><p>Watermarking measures generation provenance. It does not settle authorship, copyright ownership or legal responsibility.</p><p>Translation looks constrained because the meaning must remain faithful to the source, but Claude still chooses nearly every output token. It can vary the word choice, register and sentence structure, so Anthropic says translated text will carry the watermark.</p><p>The rough spectrum looks like this.</p><pre>Creative writing         strong signal<br>Long-form generation     strong signal<br>Translation              strong signal<br>Summarisation            strong signal<br>Heavy rewriting          strong signal<br>Short factual answers    weak signal<br>Light editing            weak signal<br>Proofreading             very weak or none<br>Executable code          weak, with more signal in comments</pre><p>Length compounds the difference. Ten tokens provide little evidence either way. Two thousand tokens provide thousands of observations.</p><h3>What happens when the text is edited?</h3><p>The signal is spread across the document. Deleting one invisible character might destroy an old Unicode watermark, but no single token carries this watermark on its own.</p><p>Change ten words in a thousand-word article and you have disturbed about one per cent of the direct token evidence. Change a hundred and you have disturbed about ten per cent. Edits can also affect the context used to score some subsequent tokens, but most of the document still contributes evidence. Detection confidence should weaken gradually rather than fall off a cliff.</p><p>A full paraphrase is different.</p><p>Take this sentence.</p><blockquote>Claude produced the report after examining the dataset.</blockquote><p>Another model could rewrite it as</p><blockquote>The data was analysed before the report was prepared.</blockquote><p>The meaning survives and almost every token changes. The watermark lived in those token choices.</p><p>Run a competent paraphraser over the entire document and it replaces most of the choices correlated with the key. Anthropic says as much. Light editing probably will not remove the watermark completely, while a rewrite that replaces essentially every word will.</p><p>To be fair, Anthropic points out that once every word has been replaced, we can argue about whether the resulting text is still the same AI-generated text. That is reasonable, but it avoids the more awkward case of one model laundering the output of another.</p><p>The problem is structural. A paraphraser preserves meaning while replacing the expression. A token-level watermark lives in the expression. As the paraphrase gets more complete, the correlation with the original key approaches zero.</p><p>A watermark that survives arbitrary paraphrasing would need to live in something the paraphraser preserves, presumably the meaning. But a system that changes meaning to encode a mark has a much worse property than a system whose mark can be removed. Reliable semantic watermarking remains an open research problem because the requirements pull in opposite directions.</p><p>There is another attack which is less obvious.</p><p>Suppose someone queries a watermarked model many times and analyses the results, looking for words that appear more often than expected in particular contexts. Given enough samples, the attacker may be able to approximate the watermark without learning the secret key directly.</p><p>This is called watermark stealing. In 2024, <a href="https://proceedings.mlr.press/v235/jovanovic24a.html">Nikola Jovanović, Robin Staab and Martin Vechev at ETH Zurich demonstrated it</a> against green-list-style schemes. They reported more than 80 per cent average success on two kinds of attack, with API query costs below US$50 in their tested setting.</p><p>The first attack is scrubbing. The stolen approximation guides a rewrite away from the watermark more efficiently than blind paraphrasing.</p><p>The second is spoofing.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eIqLi4uVudFU4R8kaCr-Ng.png" /></figure><p>Spoofing creates text that a detector attributes to a model even though the model did not generate it. Someone could fabricate a document, apply an approximation of the watermark and manufacture apparent evidence that a named company’s model produced it. The consequences depend on what the document says, and some of them are not pleasant.</p><p>We should be careful with the comparison. The ETH Zurich work targeted distribution-modifying schemes in the green-list family. SynthID’s non-distortionary, context-sensitive construction is a harder target because it leaks less information through changes to the output distribution. There is no public evidence, however, that Anthropic’s production implementation is immune to watermark stealing at scale.</p><p>Nobody should treat a detector result as evidence in a consequential decision until that uncertainty has been resolved.</p><h3>What can the detector prove?</h3><p>Anthropic therefore describes its planned detector in terms of likelihood. The question is how likely it is that a passage was partly written by Claude. The company has not yet published the operating characteristics of its production detector, including its thresholds and measured error rates. Those numbers will determine how much confidence anyone should place in a result.</p><p>There is also a fundamental asymmetry.</p><p>A positive result on a sufficiently long passage can be meaningful. It says the text’s choices correlate with Claude’s secret watermark far more strongly than chance would normally produce.</p><p>A negative result tells you much less. It is consistent with human writing, but also with another AI model, an older Claude model, a thorough paraphrase, a short answer, heavily constrained factual text or code. No watermark detected does not mean no AI was involved.</p><p>That is almost the reverse of what many organisations want. Schools, publishers, journals, courts and employers would like a machine that certifies human authorship. This technology cannot do that. A product claiming otherwise would be promising much more than the watermark can deliver.</p><p>Watermarking should also be kept separate from existing AI-text detectors. Services such as <a href="https://www.pangram.com/">Pangram</a> look for stylistic patterns that models tend to produce. Anthropic itself points to habits such as the “this isn’t X, it’s Y” construction and the model’s tendency to overuse certain adverbs. A style detector makes a heuristic guess without a secret key. <a href="https://doi.org/10.1016/j.patter.2023.100779">Those systems have generated false accusations against students, particularly people writing in a second language</a>.</p><p>A watermark detector performs a keyed statistical test with a calculable false-positive rate. It still makes mistakes and its result still needs interpretation, but it is a different and better-founded instrument.</p><p>So why bother if a determined person can defeat it with another model and a paraphrasing pass?</p><p>The best analogy may be a lock on a door. A lock does not stop a determined burglar. It deters casual entry, establishes that entry was unauthorised and raises the effort required to get around it. Watermarking will not stop a sophisticated influence operation. It may expose casual undisclosed AI generation, give platforms a signal they do not currently have and let organisations test provenance claims instead of accepting them on trust.</p><p>An Anthropic engineer described it during the August discussion as imperfect, editable and a first step. That seems the right register.</p><p>The danger is not simply that the watermark can be removed. The larger danger is that institutions will treat a partial, one-way and defeatable signal as proof, then use it to make decisions about grades, jobs or reputations.</p><p>Hiding a signature in the randomness a model already uses is elegant engineering. Doing it without making the writing worse is an achievement.</p><p>It is still not a lie detector. It cannot tell you whether somebody did their own thinking.</p><p>For that, you still have to read what they wrote and ask them about it.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b10712c2a347" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Nobody Wants the Manual]]></title>
            <link>https://medium.com/@sausheong/nobody-wants-the-manual-14554ed0d5d1?source=rss-a358058b2410------2</link>
            <guid isPermaLink="false">https://medium.com/p/14554ed0d5d1</guid>
            <category><![CDATA[fiction]]></category>
            <category><![CDATA[wuxia]]></category>
            <category><![CDATA[short-story]]></category>
            <category><![CDATA[comedy]]></category>
            <dc:creator><![CDATA[Sau Sheong]]></dc:creator>
            <pubDate>Sun, 30 Aug 2026 03:54:08 GMT</pubDate>
            <atom:updated>2026-08-30T03:54:08.284Z</atom:updated>
            <content:encoded><![CDATA[<h4><em>A True Account of the Bitter Bamboo Affair, by Du Asheng of the Iron Gate, Who Was Present Throughout</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JQ-jh5X4C8fZk-eVeWZTzg.png" /></figure><p>I have knocked a post clean out of the ground.</p><p>Not a stake. Not one of those bamboo things that come up if you breathe on them. A post, three feet down in packed clay, sunk by Mistress Ge of the Old Kettle, who does not do a job twice. I took it out of the earth in her courtyard at Sanchakou in front of forty-one of the leading martial figures of the age, and I was twenty at the time, and there are mornings even now when I wake and remember that before I remember my own name.</p><p>Master Pang used to say a story should start from the hip. I never found out what he meant, so I shall start at the front.</p><p>It began with a dead man, which sounds worse than it was.</p><p>Nobody killed him. He stopped about three li short of the inn, the way people do, and the carter brought his pack in, and Mistress Ge put it on the lost property shelf between a hat and a birdcage. In the pack were a spare shirt, a comb, four coppers and a blue book.</p><p>A peddler with one bad eye saw the blue book while waiting for his noodles. He left without paying for the noodles.</p><p>Eleven days later there were forty-one of us in a nine-room inn.</p><p>We of the Iron Gate got there first and took the east wing, on the grounds that we had got there first. This held for about eleven hours.</p><p>The Green Cloud came in the next morning on a mule cart with Madam Xie sitting bolt upright in the middle of it. The first thing she did was walk the whole east wing with her hands behind her back, looking at the doors. The second was to ask Mistress Ge which rooms had gone and to whom and in what order. The third was to take the west wing and somehow appear to have won.</p><p>A monk called Jingtan arrived on foot with two novices and asked for the cheapest room. He was told the price. He said that would do. Nobody in that courtyard had ever heard a monk agree to a price, and it was generally felt that he might have made an effort.</p><p>Old Man Cui of the Southern Fist came with three carts, a gout stool, his grandson Cui Dabao, and Cui Dabao’s mother. The Whip Hall of Xiangyang sent Mistress Bo and four women who never once sat down in three weeks. The Nine Rope people came up from the river under a boatman named Qiu, who spent the entire visit looking at the ceiling beams as though costing them. The Cold Spring Hall sent Master Yan, so thin that when he turned sideways in a doorway you thought for a moment he had left.</p><p>Four more schools came in whose names I never troubled to learn. One of them brought a banner. I thought that was showing off, and said so.</p><p>Eleven parties in nine rooms, and not one of them would say why they had come. Everybody had come about a horse, or a cousin, or the road. Boatman Qiu said he was there on business, and on the fourth day somebody finally asked what business, and he said timber, and the conversation did not recover.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2xbtewJb4hPqZ83zNPtfdw.png" /></figure><p>The courtyard filled with people doing forms at each other in a pointed way. If you wanted to cross it you went round by the wall. The inn ran out of vinegar on the second day. The nearest market was the better part of two days off, and nobody was willing to be the one who left, so it never came back.</p><p>The place had a cook.</p><p>His name was Han, he was somewhere near forty, and he was built like a granary door. I got in with him early. If you are twenty and sleeping nine to a room with fellows who snore like a Buddhist funeral, the kitchen at four in the morning is the only civilised address in the building.</p><p>He was always in it. A stove, a fish slab, a table with some papers under a chopping board, a shelf of pickling jars, and Cook Han, doing something slow to millet.</p><p>“You’re up early,” I said, the first morning.</p><p>“Yes,” he said.</p><p>He ate what he cooked, more or less. Millet congee, whatever vegetable had gone too soft to sell, water. There was a bottle of decent wine kept behind the flour for guests who asked for it, and in three weeks I never once saw him take it down for himself. He had never taken on a boy to help him either, though half the inns on that road ran two cooks and an apprentice to do less than he did alone, and when I asked him why, he said an extra pair of hands in his kitchen was an extra pair of hands doing it his way, which might have been a joke, though he did not smile when he said it. He had not missed a morning, Mistress Ge told me once, since a fever some years back, and he did not think it worth mentioning himself.</p><p>I sat on the flour barrel most nights after that and told him things. The Iron Gate. My prospects, which were good. A girl in Pingdu, who I shall not go into, and did not need to, because by the third day there was a considerably better one on the premises.</p><p>Xie Wanniang was Madam Xie’s grand-niece, nineteen, and had been brought along to carry things.</p><p>I got myself introduced on the second afternoon by walking into her while looking somewhere else, which cost a basket of turnips and was money well spent.</p><p>“You’re the Iron Gate one,” she said.</p><p>“Du Asheng.”</p><p>“You snore.”</p><p>“I sleep on the east side. You can’t hear me from the west.”</p><p>“Everyone can hear you from the west.”</p><p>She picked up her turnips and went. I stood in the yard a while feeling that we had understood one another.</p><p>The difficulty was Lu Xiaoshi.</p><p>Lu Xiaoshi was twenty-two, Green Cloud, and the owner of a sword with a name on it. The name was Autumn Rain. A man of twenty-two has no business naming a sword. He managed to say it twice before supper.</p><p>He wore his hair in a way that must have taken a servant half an hour. He laughed like a door on a bad hinge. And he was never more than three respectful paces from Wanniang, saying something low that made her put her chin down.</p><p>On the third morning he beat me at the well.</p><p>I want to be fair to the man. It was not a duel and no words were said. We went for the same bucket at the same moment, there was a certain amount of work over the rope, and he came away with the bucket and I came away with a wet sleeve and the firm impression that Lu Xiaoshi had put in a great many quiet hours on his wrists.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rNpMJJCa7daBORGIg2MNfQ.png" /></figure><p>Wanniang was at the kitchen door for part of it. Not all of it. I established afterwards that she had come out towards the end and could not have seen the sleeve.</p><p>They sent to Pingdu for an appraiser and got Scholar Mo, who authenticates martial arts manuals for a living. I had not known this was a trade. Apparently it is crowded.</p><p>He shut himself in the kitchen with the blue book for two days. Cook Han fed him and worked round him and did not appear to notice that the most famous object in three provinces was sitting where the fish usually went.</p><p>Scholar Mo worked from a copy of his own making the whole time, a fair transcript in his own hand, since an appraiser does not turn thirty-one leaves of four-hundred-year-old paper more than he must. When he carried the original through to the main room on the third day, the transcript stayed where it was, on the kitchen table, under the chopping board.</p><p>I got at Scholar Mo once, in the passage, on the first evening. It seemed to me that a quiet word between two men of the world might save everybody a great deal of standing about.</p><p>“Is it real.”</p><p>“You are the Iron Gate one.”</p><p>“Du Asheng. Is it real.”</p><p>“It is nearly supper,” said Scholar Mo, “and I have been reading since yesterday morning, and I am now going to sit in the yard and look at nothing whatever.”</p><p>Which struck me as evasive. Looking back, I think the poor devil was tired.</p><p>On the third day he came into the main room where the forty-one of us were sitting, put the book on the table and laid his hand flat on it.</p><p>“It is the Bitter Bamboo Manual,” he said.</p><p>The room went up like a stall fire. Somebody knocked a jar off the end of a table and it broke, and Mistress Ge wrote it down. My hands had gone cold and I remember hoping the business would be finished in time for breakfast.</p><p>“Complete,” said Scholar Mo, when the room let him. “Thirty-one leaves, none wanting, one hand throughout. I have set four passages against the Wuyang fragments and they agree. I would put my licence on it, and I have a licence, which is more than most of my colleagues can say.”</p><p>Master Yan asked something about the paper. Scholar Mo answered at length, and Master Yan sat down with the look of a man who has had a tooth out and been shown the wrong one.</p><p>Then Scholar Mo looked out over the book at the lot of us with an expression I could not read. I put it down at the time to scholarship.</p><p>“Perhaps a demonstration,” he said.</p><p>They wanted somebody young with no reputation to spoil.</p><p>There was some looking about. Lu Xiaoshi came half out of his seat, which I saw and have never mentioned to a soul until now, and then my shifu said my name in the voice he generally kept for informing me that a horse wanted rubbing down.</p><p>I went out. The forty of them came out after me and stood along the walls. Wanniang was at the end of the row nearest the kitchen with a bowl still in her hands.</p><p>Scholar Mo read me the first exercise of the first chapter. It took about as long as boiling water and it was not a technique at all. It was a way of putting the back foot down and letting the hip come late.</p><p>I got it wrong. Somebody at the back said something to somebody else. I got it wrong again and heard the hinge.</p><p>The third time I set the back foot, let the hip come late, and put my palm flat against the post.</p><p>Three feet of packed clay let go at once. The post came up out of the ground in a spray of muck, cleared the courtyard wall, and landed in the vegetables.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JQ-jh5X4C8fZk-eVeWZTzg.png" /></figure><p>I did not hit it hard, and I want that on the record, because a great deal of rot has been talked since. I hit it the way you would knock on a door.</p><p>Nobody spoke. Behind the stables a mule said something.</p><p>“Well,” said Old Man Cui.</p><p>“Yes,” said Madam Xie.</p><p>I looked at my own hand, which had done this without consulting me, and a great calm came over me. The age had been waiting for Du Asheng, and here he was.</p><p>Mistress Ge fetched her book and wrote down the post.</p><p>At dinner that evening Wanniang came round the end of the table and asked me to do it again.</p><p>“There’s the other one by the stable,” she said. “Aunt says you won’t.”</p><p>Now, I would have done it. There was no reason on earth why I should not have done it, and I had every intention of walking out to the stable and doing it. What stopped me was that somewhere between the courtyard and the dinner table I had lost the thing altogether. I could not have told you at that moment which foot went down first.</p><p>So I mentioned the wrist.</p><p>I said the post had wrenched something in my wrist when it came out of the ground, and that a day or two would see it right. She said what a pity. Then she went back down the table and said something to her aunt, and her aunt said something back without turning round, and the pair of them got on with their supper.</p><p>I went out to the stable at the third watch to do it again.</p><p>I am putting this in because there is no getting away from it now.</p><p>I had the movement. I had watched my own foot do it. I went down there in the dark with the vegetables on one side and the wall on the other, set the back foot, let the hip come late, and nothing whatever happened except a certain amount of pain in the wrist.</p><p>I did it forty or fifty times. Some of them felt very nearly right.</p><p>Cook Han came out at about the fourth watch to see to the fires. He set his lamp down on the end of the table, by the chopping board and the pages that had sat under it since the appraiser carried the manual through to the main room, and stood in the doorway a moment looking out at me. Then he went in again. He never mentioned it, then or afterwards, which I have always counted to the man’s credit.</p><p>Master Yan asked me the next morning. Two of the Whip Hall women asked me at noon. Boatman Qiu asked twice on the same day, once at the well and once outside the stables, and I formed the view that Boatman Qiu was not a subtle man.</p><p>Inside a week the wrist had become a considerable thing. It had a history. The post had wrenched it, the well had aggravated it, and there was an old weakness in it from a bout at the Iron Gate two winters before which I had never mentioned to anybody, for the reason that it had not happened.</p><p>I said I would show them all before we broke up. Everybody was very decent about it.</p><p>Scholar Mo let the room settle, once the fuss had died down, then poured himself tea and took a shocking time about it.</p><p>“Before custody,” he said, “there is the preface.”</p><p>“Read it,” said my shifu.</p><p>“I shall summarise. It runs to four pages.” He turned the book round so nobody could read over his shoulder, which I thought a bit thick. “The method takes eleven years. Not eleven to mastery. Eleven before there is a single form in it you may use on another human being.”</p><p>“Every school says that,” said Old Man Cui.</p><p>“Every school says it. This one gives figures.”</p><p>Eleven years. I did the sum and got thirty-one. Thirty-one is nothing. Thirty-one is a boy in a hurry.</p><p>“He rises one hour before first light and practises alone. Alone is written three times. He may not be watched, and he may not teach any part of it to anybody, and there is a warning attached to that in the fourth chapter which I would rather not read out.”</p><p>“Diet,” said Madam Xie.</p><p>“Millet congee, one boiled vegetable, water. No wine, no meat, no salt past a pinch, no strong flavour of any kind. There is a line about garlic that I can make nothing of at all.”</p><p>I have eaten worse in our own refectory, and I was still thinking so when he reached the next one.</p><p>“And no women or men for the eleven years. The text gives a reason. I am afraid the reason holds.”</p><p>There was a general noise. I did not look at the end of the row nearest the kitchen.</p><p>“Then there is the counting clause.”</p><p>“What,” said Madam Xie, “is the counting clause.”</p><p>“Three days missed in a row, at any point, for any cause, and the eleven years begin again from the first morning.”</p><p>“Illness,” said my shifu.</p><p>“Any cause.”</p><p>“Travel,” said Boatman Qiu.</p><p>“Any cause.”</p><p>“A death in the family,” said Mistress Bo.</p><p>“Madam,” said Scholar Mo, “any cause,” and drank his tea.</p><p>Forty faces round that room went to work on the arithmetic at once, and I sat there rather full about the chest, because it seemed to me that every one of them was working out how to make the sacrifice.</p><p>That was my reading. Other readings have been put to me since and I do not accept them.</p><p>What followed took two days and I have not seen anything like it before or since.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*krNybT_5fIKyt7mPzEi3eg.png" /></figure><p>My shifu spoke first and spoke beautifully. The Iron Gate covenant bound him to teach eleven students daily. The manual forbade teaching. He could not throw over eleven young men for a book. There was real pain in the man’s voice, and he sat down looking a decade lighter than he had stood up.</p><p>Madam Xie rose next. Her line went by blood alone, she said, and she was sixty-one, and eleven years would put her at seventy-two, and she would not insult the room by pretending she had that kind of time left in her.</p><p>Then, having just heard my shifu explain at length why he could not take it either, she turned and offered him the manual anyway, in terms so handsome that a woman two seats along began to cry. This is not as strange as it sounds. It is the custom on these occasions to name the worthiest person present regardless of what that person has already said, and everybody present understood it as custom, and nobody expected it to work.</p><p>My shifu said he could not possibly.</p><p>Old Man Cui was carried in still on his gout stool, his bad foot up on the cushion where it had been all through the journey, and said the whole business was absurd at his age, and put up Cui Dabao. Cui Dabao’s mother, who had not opened her mouth since the day she arrived, mentioned that the boy was to be married in the spring.</p><p>That row ran an hour and passed through three languages. At the height of it Cui Dabao said “Ma,” and was put away like a chair.</p><p>Mistress Bo said the Whip Hall’s whole method lived in the wrist, and the manual’s foundation year was all hip, and that grafting the one onto the other would be like putting a saddle on a duck. Nobody could answer this, and four people took out their brushes and wrote the line down word for word, as though it settled something.</p><p>Boatman Qiu said his people fought on boats, and there was no boat afloat on which a man could rise an hour before light and practise alone, and anyone who thought otherwise had never been on one.</p><p>Master Yan said nothing for a long while and then observed that the Cold Spring Hall had a rule about diet. He was pressed on the rule. The rule, it emerged, was that they ate whatever was going.</p><p>Then everybody turned to the monk, and for ten minutes he looked like the answer everyone had been waiting for. The diet was nothing to him. The rest was nothing to him. Solitude, he said, was practically a holiday. Then he asked one question about the hour of practice, got his answer, went quiet, and counted on his fingers.</p><p>“It sits across morning devotions,” he said. “I should have to move devotions.”</p><p>“Could you not move devotions,” said Madam Xie.</p><p>“I could not move devotions. Devotions have been at that hour since the third year of Yuanhe. I am seventh in seniority in a house of forty and I am not going to be the man who moved devotions.”</p><p>Which is when I stood up.</p><p>“Shifu. I’ll take it.”</p><p>Nobody spoke for a moment. Behind me I heard a bowl set down hard enough that I knew someone was about to come and get me. Off to one side, Lu Xiaoshi had his eyes fixed on the ceiling beams, the particular fixed stare of a man trying not to laugh.</p><p>“Sit down, Asheng.”</p><p>“I’m twenty. In eleven years I’d be thirty-one.”</p><p>“Sit down.”</p><p>“And you’d be sixty-four.”</p><p>I have gone over that remark on a number of quiet evenings.</p><p>Two of the Iron Gate seniors took me out by the elbows, which I could have prevented and chose not to. The last thing I heard was Old Man Cui saying the boy had spirit and my shifu saying something I did not catch.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QtkvMbtrlyvNxr7CLO0vvg.png" /></figure><p>I listened at the shutter, which I am not proud of and would do again.</p><p>They had got on to who was worthy. It went round and round. Twice I heard could not possibly, and once I heard two men both on their feet insisting the other was the greater, in voices that had climbed a good deal, and Mistress Ge saying something about jars.</p><p>Once, in a gap between two of the finer speeches, I heard Boatman Qiu say that nobody in that room was ever going to stand up and take it, that everybody in the room knew it, and that the real question was not who deserved the thing but what arrangement would stop somebody taking it quietly once the rest of them had gone home. Nobody answered him. After a moment somebody picked the worthiness business back up exactly where it had left off, and the debate went on as though he had not spoken.</p><p>I took it for Boatman Qiu being difficult, the way he generally was, and went back to listening for something more interesting. It was the better part of four years before I understood he was the only man in that room who had said anything true.</p><p>Then I went and sat on the flour barrel while Cook Han did things to a fish.</p><p>“They wouldn’t have me.”</p><p>“No,” he said.</p><p>“Modesty, mostly. Nobody wants to be seen snatching.”</p><p>He turned the fish over.</p><p>“I’ve never seen anything like it. Man after man standing up and putting it aside for somebody worthier. Somebody ought to tell the poets.”</p><p>“Mm.”</p><p>“As Master Kong has it, water is good at benefiting all things and does not contend.”</p><p>“That was Laozi,” said Cook Han. “Master Kong never went near water. He was talking about archery.”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AM9B_oI_nDmbeoYcn3T7AQ.png" /></figure><p>Then he gave me the good half of the fish. I have known princes who could manage neither the correction nor the fish.</p><p>Somebody tried to steal it on the second night of the debate.</p><p>He got as far as the main room and was taken by one of the monk’s novices, who by the sound of it sat on him. There was a lamp lit and a good deal of movement in the passages, and I put my head out of my door and was told by a senior to put it back in.</p><p>In the morning the assembly considered the matter and reached a finding, and the finding was that a passing thief from outside had made an attempt on the inn, which showed how urgent the question of custody had become.</p><p>I thought that a little weak, since the man had known the room and the shelf and had come in his stockings. But everybody seemed satisfied, and it was remarked three or four times over the following days how fortunate it was that the schools present were all above that sort of thing.</p><p>A junior of the Cold Spring Hall left for home that afternoon on account of a family matter. Master Yan saw him off and was very cold about it, and I supposed the family matter must be grave.</p><p>Madam Xie broke it in the end, and everybody went at the compromise like men coming off a boat.</p><p>The manual would stop at the Old Kettle, sealed in a lacquer box, in a niche in the main room, under a stone tablet recording that the Bitter Bamboo Manual rested there in trust, awaiting one whose destiny was ripe.</p><p>There is no arguing with a ripe destiny. Nobody was bound to anything, and all forty-one of us went home custodians of something famous. There would be an inspection once a year by rotation. There would be a fund, subscribed by school size, which took most of an afternoon and was the only part of the entire business in which anybody raised their voice about money.</p><p>Master Yan asked whether any copy of the text existed. Scholar Mo said a working transcript had been made for collation, as was standard in his trade. Master Yan said the trust concerned the original. Scholar Mo agreed that it did. Everybody went back to the fund.</p><p>Scholar Mo did not mention, then or afterwards, that he had not laid eyes on his own transcript since he carried the original out of that kitchen. It did not occur to him to wonder about it. A working copy is not the thing itself, and no scholar loses sleep over his own handwriting.</p><p>Mistress Ge got a yearly sum out of it, which she talked upwards twice while the cheering was still going on.</p><p>The tablet was cut in Pingdu by a man who charged by the character.</p><p>It came back on the ninth day on a handcart. Four of us carried it in. It was a handsome piece of stone, and it recorded that the Bitter Gourd Manual rested there in trust.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bm-kgwj29XZcF5MuV07kRw.png" /></figure><p>The silence was not unlike the one after the post.</p><p>Master Yan said the stone would go back. The carver’s boy, who had come with the cart, said the stone would not go back, and produced a written order with the fee on it and Master Yan’s own mark at the foot.</p><p>The debate that followed was in some ways the finest of the whole three weeks. It was settled at last that a second and smaller stone would be set beside the first, recording that the manual referred to was the Bitter Bamboo Manual and that the larger stone was to be understood accordingly.</p><p>Boatman Qiu said afterwards that the two together read worse than the one alone. I did not see it at the time. I have seen it since.</p><p>The sealing was done on a clear morning with everybody in their good coats.</p><p>There was a proposal that all eleven schools be named on the smaller stone. It was carried with enthusiasm and then had to be gone into, since the schools would have to appear in some order, and the discussion of what that order should be ran from the middle of the morning to well past noon and produced two withdrawals and a reconciliation. It was resolved in the end that no names would appear at all, which everybody agreed was more dignified.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*f2aWqypqssbLQ52yTX1AUA.png" /></figure><p>My shifu and Madam Xie set the box in the niche together, after a short discussion about hands which took a quarter of an hour and involved a diagram. The monk said something suitable. Mistress Bo’s four women stood in a line and did not sit down.</p><p>Old Man Cui cried and let it be thought it was for the manual.</p><p>I got two words with Wanniang on the road outside while the carts were loading, and I have always thought it went off rather well.</p><p>“You stood up,” she said.</p><p>“I did.”</p><p>“In front of everybody. For eleven years of congee.”</p><p>“A man does what a man should do.”</p><p>“Yes,” she said. “I expect he does.”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-AKSsZ93xhsOag6ZeMl7aA.png" /></figure><p>Then she went up on the mule cart, and Lu Xiaoshi handed the baskets after her, and I stood in the road and watched them out of sight and felt as fine as I have ever felt in my life.</p><p>The inn was empty that last night but for the Cui carts.</p><p>“They’ll be back every year,” I said. “To look at the seal.”</p><p>“Mm.”</p><p>“One of these days somebody’s destiny will ripen and they’ll open the box and there’ll be a scene.”</p><p>Cook Han put a lid on something.</p><p>“How’s the wrist,” he said.</p><p>“Much better. Thank you.”</p><p>“Mm,” said Cook Han.</p><p>I came back four years later about some horses.</p><p>The inn was the same and Mistress Ge charged me more. Both stones stood in the main room, the big one and the little one, and Boatman Qiu had been quite right, and I read them twice while my tea went cold.</p><p>Mistress Ge gave me the news of the road. Old Man Cui had died. Master Yan had come up in the spring for the inspection and had spent an hour on the seal with a glass. And Madam Xie’s grand-niece had married the Green Cloud boy, the one with the sword with the name on it, at Yongzhou, two years since, and there was a child.</p><p>I took it as well as a man can. She was always going to want a quiet life, and Lu Xiaoshi will give her one, and I have no doubt he is very happy in his way.</p><p>Then I put my head into the kitchen out of sentiment, found nobody in it, and went round the back.</p><p>Cook Han was in the yard with his sleeves tied back, working at something slow against a post.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tZzopZRy-NTIIIeHL8Rgig.png" /></figure><p>I watched a while.</p><p>I am not a vain man, but the thing must be said. What that good fellow was doing behind a kitchen at Sanchakou in the last of the light was, near enough, a version of the movement I performed in that same courtyard four years before, in front of the assembled schools, on the celebrated occasion. Back foot down. Hip coming late.</p><p>Only he did it a great many more times than I ever did, and slower, and about half of those times the post did not move at all, which I put down to a want of confidence on his part. Once or twice, when it did move, he went straight on into something I had never seen before, some low turning business with the other hand. A man teaching himself off the memory of one demonstration is bound to invent a piece here and there to fill the gaps, and I supposed this was one of them.</p><p>He had it off me. He must have stood in that doorway the whole afternoon with forty-one of the great names of the age in front of him, and out of the lot of them he had taken away the one thing worth taking, which was Du Asheng and the post.</p><p>I was touched.</p><p>“Not bad,” I said. “Shoulder wants to be lower. I’d show you, but the wrist catches in cold weather.”</p><p>He watched anyway, the way he always watched, with his whole attention.</p><p>“Thank you, sir,” he said.</p><p>“Not at all. If you’re ever stuck, ask for me. Iron Gate. They’ll know the name.”</p><p>He said he would, and went in to start the fish.</p><p>I walked back through the yard feeling that a man does what he can. There was a fresh post in the ground by the wall. Fifth or sixth, going by the patches.</p><p>Mistress Ge really wants to get better clay in.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=14554ed0d5d1" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Will coding agents make the software team disappear?]]></title>
            <link>https://medium.com/@sausheong/will-coding-agents-make-the-software-team-disappear-bc50fe94384e?source=rss-a358058b2410------2</link>
            <guid isPermaLink="false">https://medium.com/p/bc50fe94384e</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[ai-agent]]></category>
            <dc:creator><![CDATA[Sau Sheong]]></dc:creator>
            <pubDate>Thu, 20 Aug 2026 08:22:27 GMT</pubDate>
            <atom:updated>2026-08-20T08:22:27.883Z</atom:updated>
            <content:encoded><![CDATA[<h4>Coding agents are changing more than how software is written. They are changing the team around it.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dYcxTZRc_5Euq1hQMLX3wA.png" /></figure><p>For the past few years, the software industry has been learning to work with machines that can write code. It began innocently enough. A coding assistant sat inside the editor, watched what a developer was typing and suggested the next few lines. Sometimes it was uncannily right. Sometimes it confidently invented a library that did not exist. Either way, the human remained firmly in charge. The machine suggested and the developer decided.</p><p>That already feels like an earlier age.</p><p>The newer generation of software agents can take a task, inspect a codebase, plan a change, edit several files, run the tests, diagnose a failure, revise the implementation and open a pull request. Given the right tools and permissions, an agent can work for minutes or hours without someone watching every keystroke. A developer can start several such jobs at once, leave them running in separate environments and return later to inspect what happened.</p><p>This is a larger change than better autocomplete. Coding assistants accelerate an activity performed by a developer. Agentic software delivery reallocates activities across humans and machines. Once that happens, the process around coding starts to move as well. Specifications become more important because an agent will happily execute an unclear request. Tests become evidence rather than a final ritual. Architecture needs to be expressed as rules that a machine can check. Work that used to move sequentially between analyst, designer, developer and tester can sometimes be completed by one person directing several agents.</p><p>And when the process changes, roles and organisational structures eventually follow.</p><p>We can already see this happening. Some companies are placing agents inside conventional software squads. Others are forming smaller teams of senior generalists who own a product from idea to operation. A few are testing the limiting case, an experienced engineer operating as a team of one with a collection of agents. Large organisations are creating central platforms that give these teams context, security, evaluation and reusable workflows. Even the boundary between people who make software and everyone else is becoming more porous, with support and operations staff making bounded product changes themselves.</p><p>I have a close view of this change because I started Giant Robots Labs in GovTech Singapore as an experimental lab for turning ideas into working products more quickly. The lab itself is an experiment in a new way to organise software delivery. I will return to what we are testing later, although Giant Robots Labs is only one small part of a much wider industry movement.</p><p>The software team is unlikely to disappear. Some teams will become much smaller, but only because more engineering capability has moved into agents, platforms, automated controls and shared specialists.</p><h3>From suggestion to delegation</h3><p>GitHub Copilot arrived in technical preview in 2021 and established the dominant metaphor for the first phase of generative AI in software development. AI was a <em>copilot</em>, the developer remained the pilot, and the unit of interaction was usually a fragment of code. Other products improved the conversation, enlarged the context window and became better at editing multiple files, but the basic relationship held. A human worked synchronously with an assistant.</p><p>The attraction was obvious. Software development contains a great deal of repetitive typing, boilerplate, syntax recall and searching through documentation. If a machine could remove some of that effort, developers could spend more time on design and difficult problems. Controlled studies produced gains in particular tasks, although the results varied by experience, task and environment.</p><p>Agents alter the unit of work. The prompt is no longer necessarily “write this function”. It may be “investigate this bug”, “upgrade these applications to a new framework version” or “implement this ticket and return a tested pull request”. To do that, the machine needs access to a terminal, repository, build system and other tools. It also needs a loop. It acts, observes the result, reasons about what happened and acts again.</p><p>That loop makes delegation possible. It also creates an entirely new catalogue of ways to go wrong.</p><p>A coding suggestion is small enough for a developer to understand before accepting it. An agent may touch dozens of files, make architectural assumptions and produce a green test suite that proves less than everyone thinks. It can follow a ticket too literally, use stale documentation or optimise for passing a check while violating the purpose behind it. A developer who runs five agents in parallel can generate more work than they can seriously review. The typing bottleneck vanishes and reappears as a judgement bottleneck.</p><p>This is why successful agentic delivery depends on the system around the model. The repository has to tell the agent how the software is organised. The task has to contain the right business and technical context. Tests and static checks have to catch meaningful failures. Permissions must limit the damage a mistaken action can cause. Logs must show what the agent did. A human must remain responsible for accepting the result.</p><p>The industry has started calling this <em>harness engineering</em>. The harness comprises the instructions, tools, context, constraints and feedback loops that make an agent useful inside a production environment. A model can supply extraordinary capability, but capability without control is a poor way to run software on which customers, businesses and public services depend.</p><h3>The OpenAI experiment and the amplifier effect</h3><p>One of the clearest examples comes from OpenAI itself. In February 2026, the company <a href="https://openai.com/index/harness-engineering/">described an internal product built under an unusual rule</a>. Humans would write none of the code. Codex generated the application logic, tests, continuous integration configuration, documentation, observability and internal tools.</p><p>The project began with three engineers. Over five months, the repository grew to around one million lines and roughly 1,500 pull requests were opened and merged. The team later expanded to seven engineers. OpenAI estimated that the product had been built in about one-tenth of the time manual development would have required. It had daily internal users and external alpha testers, so this was more than a benchmark exercise, although it remained a greenfield experiment run by the company that made the agent.</p><p>The line count is irrelevant. Millions of lines can be an achievement or a maintenance problem, and often both. The revealing change was what the engineers did all day.</p><p>Early progress was slow because the environment was underspecified. The agents lacked the abstractions, tools and repository structure needed to turn high-level goals into dependable changes. Human engineers therefore worked on scaffolding, architecture, legibility and feedback. They designed an environment in which agents could do better work. When an agent repeatedly struggled, the team did not merely correct the immediate output. It asked what capability or constraint was missing from the environment, then improved the harness so subsequent agents performed better.</p><p>This reverses the usual relationship between application and platform engineering. Traditionally, the platform helps people build the application. In an agent-first project, the human team spends much of its effort engineering the production system that builds the application. Instructions, tests, repository conventions and architectural checks become part of that system. Humans design the line, decide what should be produced and inspect the output. Agents perform much of the fabrication.</p><p>The experiment shows what a carefully designed environment can make possible. It does not mean that giving coding agents to any engineering organisation will produce the same result. <a href="https://dora.dev/research/2025/dora-report/">Google’s 2025 DORA research</a>, based on nearly 5,000 technology professionals, concluded that AI acts as an amplifier. Capable organisations can gain from it, while weak processes, poor documentation and unreliable delivery systems can become worse.</p><p>This is the tension running through the current evidence. Agents can produce striking local gains, but the organisation determines whether those gains survive contact with production. A company with fast tests, clear ownership, modular systems and dependable deployment can turn agent speed into customer value. A company with ambiguous requirements and three-week approval queues may simply generate work faster than it can absorb it.</p><h3>Small teams need stronger shared systems</h3><p>Agile software development normalised the small, cross-functional squad. Instead of moving a specification through separate departments for analysis, design, programming, testing and operations, organisations placed several disciplines together around a product or value stream. The approach reduced hand-offs and shortened feedback cycles, although reality often retained a surprising number of tickets, queues and committee meetings.</p><p><em>Agentic software development </em>pushes in the same direction. If one experienced engineer can use agents to work across front end, back end, infrastructure, tests and documentation, the squad requires less permanent implementation capacity. If an agent can explain an unfamiliar repository and apply established patterns, a specialist does not have to perform every routine change personally. If product artefacts can be generated and revised during a stakeholder conversation, some sequential analysis and design stages can collapse.</p><p><a href="https://openai.com/index/endava/">Endava, the global software services company, offers one example</a>. It says it uses Codex across requirements analysis, design, specifications, development and operations. Senior architects encode their viewpoints so junior developers can receive guidance while they work, allowing one person’s experience to reach several teams concurrently. In one engagement, the company recorded a two-hour discussion with legal specialists about reviewing thousands of pages of contracts. It used the transcript to produce a working specification in two further one-hour meetings, compressing what it said would normally have taken a week or two of revisions.</p><p>This is a vendor-hosted customer story, not a controlled comparison. Yet it illustrates the organisational mechanism. Knowledge that once travelled through meetings, pairing and review can partly travel through an agent. Activities that were separated by specialist hand-offs can be drawn into a single working loop.</p><p><a href="https://www.thoughtworks.com/insights/articles/preparing-your-team-for-agentic-software-development-life-cycle">Thoughtworks has described the likely destination</a> as smaller stream-aligned teams supported by a common agent platform (AI/Works) and knowledge network. Delivery teams work more independently because they can obtain routine architectural, platform and policy help through self-service interfaces. Central teams remain, but their expertise is packaged into reusable code, knowledge and controls. Human specialists concentrate on improving those assets and handling exceptional cases.</p><p>Three broad operating models are appearing today.</p><p>The most familiar is the <em>agent-augmented conventional squad</em>. The reporting lines and roles remain largely intact, while agents generate tests, investigate incidents, update dependencies, prepare migrations or turn tickets into draft pull requests. <a href="https://www.anthropic.com/customers/palo-alto-networks">Palo Alto Networks took a process-led version of this route</a>. Its engineering team mapped the software delivery lifecycle to identify delay and error points before introducing AI. The company later reported a 20 to 30 per cent increase in feature velocity and a reduction in onboarding time from months to weeks across an initial 2,500 developers. The claims come from an Anthropic customer case, but the sequence is instructive. The company studied the delivery system before changing it.</p><p>The second model is the <em>small outcome-owning cell</em>. A few senior generalists own a product area from discovery to operation and use agents as elastic implementation capacity. Product and design may work across several cells. Security, architecture and SRE supply shared platforms and consult on exceptions. This reduces some coordination cost without concentrating everything in one person. It also provides continuity when somebody takes leave or a difficult incident needs a second pair of human eyes.</p><p>The third is the <em>federated organisation supported by a common agent platform</em>. Delivery teams remain distributed, while senior expertise, approved models and common workflows are managed centrally. <a href="https://withwillow.ai/blog/wix-case-study">Wix offers an infrastructure example</a>. Its AI Core team reportedly built a common tool and context layer supporting hundreds of internal tools and hundreds of thousands of weekly calls across engineering, product, design and corporate functions. The figures come from an implementation-partner case study, but the organisational choice is clear. Instead of allowing each team to assemble an unrelated collection of agents and permissions, the company created a common access layer.</p><p>These models can coexist. A bank might keep conventional squads for its core ledger, use small outcome cells for customer workflows and provide all of them with an enterprise agent platform. It may also let operations or support staff make low-risk changes through controlled workflows. <a href="https://www.anthropic.com/customers/gumroad">Gumroad says customer-support staff use Claude</a> to locate code, triage issues and sometimes fix them. <a href="https://www.anthropic.com/customers/rakuten">Rakuten says non-engineers can contribute to coding projects</a> when given appropriate context and guidelines.</p><p>That permeability can shorten the distance between a user problem and a product response. It can also create an unholy wreck if “anyone can build” is interpreted as “nobody needs engineering”. A support specialist may be perfectly placed to correct a label or repair a narrow workflow. A change to authentication, billing or data retention carries consequences that may not be visible in the interface. The software still needs owners, controls and review based on risk.</p><p>A smaller team does not mean specialist knowledge has become unnecessary. Much of that knowledge has moved. It may now live in platform code, an evaluation suite, a policy engine, a repository instruction file or an agent maintained by specialists elsewhere. The people visible in the delivery cell shrink while the institutional machinery behind them grows more capable.</p><h3>Can one person become a software team?</h3><p>A <a href="https://arxiv.org/abs/2605.18461">2026 research preprint</a> reports a single enterprise case of the idea taken close to its limit. A staff engineer in a large Brazilian financial institution completed a brownfield product initiative with four AI agents under a specification-driven process. The work had originally been scoped for a four-person squad over six sprints. According to the paper, the engineer delivered it in three sprints, 90 per cent of AI-generated code passed its first review, all integration tests passed, the product met WCAG 2.1 AA accessibility requirements and direct staffing cost fell by more than 85 per cent.</p><p>Those figures will delight anyone preparing a cost-reduction presentation but we should be careful to take it at face value.</p><p>It was a single case. The institution was not named. The engineer was a staff-level practitioner with deep institutional knowledge. The project was bounded and much of its success depended on the quality of the specification. It also took place inside an existing enterprise with standards, systems, infrastructure and reviewers. The one-person squad was supported by an organisation built by many people over many years.</p><p>The study’s conclusion is more useful than its headline. AI multiplied the experienced engineer who remained. Specification quality and institutional knowledge were the binding constraints.</p><p>One-person delivery can therefore work under particular conditions. The product boundary must be clear. The codebase needs to be legible. Tests and production signals must provide fast feedback. Deployment and rollback should be routine. The work needs to fit within the cognitive capacity of one accountable owner, even if agents perform much of the implementation. Specialist advice and independent review must be available when risk demands them.</p><p>It becomes a poor model when the problem is politically ambiguous, when user needs are contested, when the system crosses several tightly coupled legacy platforms or when a mistake can cause material financial, safety or privacy harm. It also creates an old-fashioned key-person dependency. The engineer may have five tireless agents, but the organisation still has only one person who understands why all those decisions were made.</p><p>People take leave, change jobs and occasionally fall ill. A conventional squad carries overlapping knowledge and can absorb the loss of one member. A team of one needs deliberate documentation, handover readiness and another human able to take over. Agents can preserve context, but a transcript of past decisions is not the same as an accountable colleague who has lived through them.</p><p>So, will one-person teams exist? They already do. Will every team become one person? Maybe, but not yet, and probably not for everything.</p><h3>My experiment at Giant Robots Labs</h3><p>The question of how small a software team can become is not abstract for me. I started <a href="https://giantrobots.tech.gov.sg/">Giant Robots Labs</a> inside GovTech’s Government Technology Office as an experimental lab. We wanted to turn ambitious ideas into working products quickly, put them in front of users and learn from evidence instead of debating assumptions for months.</p><p>AI tools widened the experiment. If an agent could help one engineer work across product implementation, front end, back end, deployment and operations, could we design a leaner unit around that capability? We call the people who own those products <em>pilots </em>(a nod to copilots), and we are currently rolling out the experiment incrementally.</p><p>The term “AI-enabled team of one” attracts attention, though it can also create the wrong picture. I do not mean an isolated engineer carrying an entire public product and all its institutional obligations alone. Our model has an inner and an outer loop. One (or maybe two) pilot(s) stay close to a product and own its direction, users, implementation, operation, cost, roadmap and eventual handover or closure. A <em>shared support crew</em> moves across the portfolio, bringing product management, design, product operations, strategy, communications, policy, compliance and governance where they are needed.</p><p>The ownership line is deliberate. The support crew helps without taking the roadmap away from the pilot. Related products can be grouped into a broader mission when they need common direction or interoperable interfaces, while each product keeps a clear owner. Different products also need different strengths. A user-facing workflow may call for a product engineer, a platform integration for a software engineer, and an agentic product for an AI engineer who understands evaluation and model behaviour.</p><p>We are early in the rollout, so I do not yet have a neat set of conclusions. That is the point of running the experiment. We are testing whether a pilot can hold product and operational responsibility without becoming overloaded, whether shared expertise can move across the portfolio without forming another queue, and whether a fast pilot can become a service that people trust and another team can inherit.</p><p>These questions are more important to me than whether a single engineer can produce an impressive prototype. Developing software is becoming easier. The harder test is whether a small accountable unit can keep learning with users, operate safely inside government and leave behind a product that is ready to grow, transfer or close deliberately.</p><p>Running an experimental lab has made me wary of confident declarations about the future of the software team. A workflow that looks extraordinary in a demonstration may fail when it encounters unclear ownership, missing context, production risk or an approval process designed for a different age. Experiments are valuable because they turn predictions into questions that can be measured.</p><p>Giant Robots Labs gives me a place to test that proposition, but it does not provide the answer for the whole industry. Our environment has public-sector constraints and responsibilities that a startup may not share. Equally, companies building commercial products face market, customer and organisational pressures that differ from ours. The useful comparison is not whose team is smallest. It is which surrounding system allows a small team to deliver a dependable outcome.</p><h3>How roles and authority change</h3><p>The most immediate question for software professionals is what happens to their jobs. Headlines tend to offer two choices. AI will replace developers, or AI is merely another tool and nothing fundamental will change. Neither account matches what organisations are beginning to do.</p><p>Developers still need technical depth, perhaps more than before. An agent can produce a convincing implementation in an unfamiliar domain, which means the reviewer must recognise failure without relying on obvious syntactic mistakes. The engineer’s daily work moves towards problem framing, architecture, environment design, task decomposition, evaluation and production ownership. Typing becomes a smaller share of the job. Judgement becomes a larger one.</p><p>This creates the product engineer in its broadest sense, someone who can move from a user problem to a running service and understand enough of each layer to direct machines and call specialists at the right time. It does not require one generic super-developer. Organisations can choose product, software or AI engineering strength according to the uncertainty in the work.</p><p>Engineering managers also face a different job. When machine capacity can be purchased by the token and several agents can work in parallel, keeping people busy is an even less useful objective than it was before. The manager has to design the delivery system. How much agent work can reviewers absorb? Which actions require approval? Where does context live? Which failures should become automated tests? When should a small team seek help rather than continue alone?</p><p>Some management devoted mainly to allocating tasks and collecting status may shrink. Work performed by agents can report its own state when the infrastructure is designed properly. Yet managers will still be needed to set priorities, resolve disagreement, coach people, manage risk and allocate scarce human attention. A fleet of agents does not decide which customer or citizen outcome deserves investment.</p><p>Smaller teams also change where authority sits. If one pilot directs several agents, that person needs more than implementation responsibility. They need authority over the roadmap, production decisions and operating cost within an agreed boundary. Platform teams decide which controls apply everywhere. Security, policy and reliability specialists define where independent approval remains mandatory. Without explicit decision rights, a smaller team inherits all the responsibility of a larger squad without gaining its autonomy.</p><p>Budgets will have to follow those responsibilities. Traditional workforce planning asks how many engineers, designers and managers a programme needs. An agentic portfolio also has to decide how much machine capacity each team can consume, which shared capabilities are funded centrally and what evidence justifies adding human headcount. These choices cannot be reduced to a rule that every team should use AI before hiring. A team may be short of implementation capacity, product judgement, domain knowledge or operational cover. Agents address some constraints far better than others.</p><p>Management spans may increase if smaller cells need less daily coordination, but that does not automatically make the organisation flatter. A manager overseeing ten pilots could spend less time on task allocation and more on competing priorities, performance, technical risk and the health of the shared platform. Alternatively, the pilots may require senior leaders who understand the product and engineering system well enough to grant meaningful autonomy. Removing a layer of coordination only helps when authority moves with the work. Otherwise, decisions travel just as far through fewer people.</p><p>Performance systems will need attention too. It becomes difficult to judge an engineer by the quantity of code produced when agents can generate it by the million lines. Organisations will have to reward problem selection, system quality, evaluation, reuse, operational outcomes and improvements to the common harness. A person who prevents five teams from repeating the same failure may create more value than someone who opens fifty agent-generated pull requests. Promotion criteria built around visible individual output will push people towards volume at precisely the moment when restraint becomes more valuable.</p><p>Cheaper implementation also changes portfolio management. Organisations can test more ideas, but they will need to close more of them. A prototype that cost little to create can still impose years of support, security and migration obligations. Small teams should therefore receive explicit authority to stop weak products as well as start promising ones. The ability to abandon an experiment deliberately may become as important as the ability to launch it quickly.</p><p>Product managers and designers do not become redundant simply because software is cheaper to produce. Cheap implementation creates more choices. Someone still has to understand users, decide which problem deserves attention and maintain coherence across a rapidly changing product. Their work becomes more continuous and less like a document handed over at the start. In smaller team structures, these specialists may travel across a portfolio while outcome owners retain their roadmaps. That works only if support arrives early enough to influence decisions rather than appearing at a gate shortly before launch.</p><p>Quality assurance moves from downstream testing towards designing the quality system. Agents can generate test cases and run regressions, but somebody must decide what should be tested and whether those tests represent the risks users face. QA specialists will increasingly work on executable acceptance criteria, evaluation suites, adversarial scenarios, production telemetry and release policy. They inspect exceptions and improve the net rather than manually catching every fish.</p><p>Platform engineering, SRE and security become more central. Higher agent throughput magnifies weaknesses in the environment. Poorly scoped credentials become more dangerous when a machine can act rapidly. Weak tests allow more defective code through. Incomplete observability makes autonomous failures harder to reconstruct. The central platform must supply isolated execution, identity, permissions, approved models, trace storage, cost ceilings, deployment controls, rollback and reusable workflows.</p><p>The platform also creates an organisational question. Who funds it, who sets its priorities and who is accountable when a common agent or control fails across several teams? If every product pays only for visible delivery, the shared machinery will be underfunded. If the platform dictates every workflow, it becomes a bottleneck. Leaders need to fund it as a product, give it clear service obligations and preserve room for local teams to extend it safely.</p><p>Policy and governance also move into the delivery system. Routine requirements can be expressed as policy-as-code and approved patterns, while humans handle ambiguous or high-impact cases. This lets low-risk changes flow without asking a committee to repeat the same decision, yet preserves independent review where consequences justify it.</p><p>The most uncomfortable consequence concerns junior engineers. They traditionally learn by doing the work that agents handle well. They fix small bugs, write routine tests, trace unfamiliar code and receive corrections in review. If an organisation removes junior positions because senior engineers and agents can produce more, it may improve this year’s output while weakening its future supply of senior judgement.</p><p>The apprenticeship will need to become deliberate. Juniors can pair with senior engineers while directing agents, review agent-generated changes before seeing the senior’s assessment, rotate through incidents and platform work, and investigate why an agent’s plausible solution failed. Organisations may use agents in teaching mode, asking them to reveal alternatives and evidence instead of delivering a finished patch. An agentic organisation without a way to develop human judgement eventually becomes dependent on a shrinking group of experts whose encoded knowledge nobody remaining can properly challenge.</p><h3>Faster coding can produce a slower organisation</h3><p>The case studies surrounding agentic software development contain some spectacular numbers.</p><p><a href="https://www.anthropic.com/customers/rakuten">Rakuten says its feature cycle fell from 24 working days to five</a> and describes engineers running several Claude Code sessions concurrently. <a href="https://openai.com/index/cisco/">Cisco reports a tenfold to fifteenfold increase in defect-remediation throughput</a> for certain workflows and more than 1,500 engineering hours saved each month through build optimisation.</p><p>These are vendor-published customer stories. They demonstrate possibilities and mechanisms, though they do not establish average effects. Companies with disappointing results rarely become glossy case studies.</p><p><a href="https://arxiv.org/abs/2507.09089">METR’s randomised study</a> of 16 experienced open-source developers working on 246 real tasks in repositories they knew well produced an awkward result. Early-2025 AI tools made them 19 per cent slower, even though the developers believed they had become faster. The study was narrow and the technology has advanced since then. <a href="https://metr.org/blog/2026-02-24-uplift-update/">METR tried a later experiment</a> and concluded in February 2026 that its data had become too biased to estimate the effect reliably, partly because developers increasingly refused to work without AI and partly because concurrent agents made time tracking difficult. The later raw results suggested some acceleration, but the confidence intervals were wide.</p><p><a href="https://www.atlassian.com/blog/company-news/ai-sdlc">Atlassian has described a similar gap at organisational scale</a>. In a longitudinal study conducted with DX, AI use increased by 65 per cent while overall developer velocity improved by no more than 15 per cent and often around 10 per cent. Its explanation is straightforward. Developers spend much of their time obtaining context, clarifying requirements, waiting for decisions, reviewing work and coordinating across teams. Faster code production does not remove those delays. It can feed them faster.</p><p>Imagine a road where one factory doubles its output but the loading dock, customs checkpoint and bridge retain the same capacity. The result is not twice as many deliveries. It is a longer queue.</p><p>Agentic organisations therefore have to optimise the whole flow from idea to production and learning. If design becomes the bottleneck, more coding agents will not help. If security approval takes three weeks, generating a patch in ten minutes changes little. If each agent opens ten mediocre pull requests, review time expands and good work waits behind noise. Local speed can make the organisation slower.</p><p>The process itself has to become executable. Specifications need enough detail for a machine to act. A useful agent-ready specification can be short, but it must state the outcome, relevant context, constraints, examples, acceptance criteria and explicit exclusions. Tasks need isolated environments and clear boundaries so several agents can work without colliding. Dependencies must be recorded somewhere durable. Asking another probabilistic model to remember the schedule is charming until two agents edit the same migration.</p><p>Completed work should return with proof. A pull request alone is insufficient. The evidence package might contain the plan followed, tests and checks run, screenshots or recordings, security results, cost, known limitations and a trace of material actions. The human can then inspect what was attempted and decide whether the evidence supports release.</p><p>Architecture also has to become more executable. A paragraph declaring that one module must never depend on another is useful to a reader who remembers it. A dependency rule in continuous integration is useful to every agent that touches the repository. The same applies to schemas, API contracts, accessibility, security and deployment policy. Repeated human review comments should gradually become instructions, tests or automated controls.</p><p>When code is cheap, teams can produce far too much of it. Duplicate abstractions, unnecessary dependencies and dead features accumulate. Documentation grows stale. Agent instructions contradict one another. OpenAI’s experiment describes recurring “garbage collection” work to keep the repository coherent. This is part of operating the system, not housekeeping to perform when everyone is free.</p><p>The easiest agentic metrics are often the most misleading. Lines of code reveal production volume, not usefulness. Pull requests reveal activity, not outcomes. Token consumption reveals cost, though not whether anyone should have asked for the work. Even time saved is slippery when the saved hour returns as twenty minutes for each of four reviewers.</p><p>Leaders need to measure the complete value stream. How long does an idea take to reach users? Where does it wait? How often does a change fail or need to be rewritten? How much reviewer attention does agent work consume? What is the cost per accepted change and, better still, per customer or mission outcome? Are on-call load and security findings rising? Can another team understand, operate and modify the product?</p><p>Cost and handover readiness deserve particular emphasis. A small team should own the cost of its agent usage so machine work does not become invisible infrastructure confetti. It should also show that another team can understand and operate the product. When an agent makes a recurring mistake, the organisation should convert that failure into a test, instruction, tool or policy that improves the next run.</p><p>This is where organisational design catches up with agent capability. Small teams shorten the inner delivery loop by keeping product and technical ownership together. Shared specialists and platforms remove outer-loop blockers without taking the product away. If those shared services become another queue, the mathematics will reveal itself fairly quickly.</p><h3>The team after the team</h3><p>The software industry started this journey by placing a helpful assistant beside the developer. It is now giving agents entire tasks and asking developers to run the environment in which those tasks are completed. The next change will be organisational. Teams will become smaller in some places, specialist capability will move into shared platforms, and roles will broaden around judgement, evidence and ownership.</p><p>At the delivery edge, small outcome-owning cells will take responsibility for products or bounded value streams. At the centre, common platforms will provide approved models, execution environments, identity, permissions, organisational context, reusable agents, evaluation and deployment pathways. Across both, architecture, security, privacy, reliability, accessibility, policy and design specialists will encode routine decisions, coach teams and review exceptions.</p><p>There will still be large teams. Complex discovery needs diverse perspectives. Major incidents need several humans who can build a shared picture quickly. Large migrations cross boundaries that no single person should own alone. High-stakes systems need separation of duties. Agentic delivery changes the minimum efficient size of some teams. It does not repeal organisational risk.</p><p>This is what we are trying to learn through Giant Robots Labs. I do not yet know how far the team-of-one model can travel inside government. That is why I’m still calling this an experiment. The useful result will not be just proving that one person can generate a product quickly. It will be discovering the support, controls and limits that allow a small team to remain accountable for what it creates.</p><p>The one-person team will be real, though it will never be only one person. Behind it will stand platform builders, shared specialists, policies, tests, accumulated knowledge and other humans who make autonomy possible.</p><p>The agent may write the software. The organisation still has to make it work.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bc50fe94384e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Transparency]]></title>
            <link>https://medium.com/@sausheong/transparency-63d689f18805?source=rss-a358058b2410------2</link>
            <guid isPermaLink="false">https://medium.com/p/63d689f18805</guid>
            <category><![CDATA[science-fiction]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[ai-agent]]></category>
            <category><![CDATA[fiction]]></category>
            <dc:creator><![CDATA[Sau Sheong]]></dc:creator>
            <pubDate>Sat, 08 Aug 2026 15:34:58 GMT</pubDate>
            <atom:updated>2026-08-09T04:48:12.670Z</atom:updated>
            <content:encoded><![CDATA[<p>“So how do you actually get into a computer?” Patrick Lim asked. “I mean physically. Where do you touch it?”</p><p>Outside the Authority’s windows, Singapore was already dressed for National Day. Red-and-white flags hung from HDB balconies beyond the civic district, and somewhere over the bay a formation of aircraft passed in rehearsal, their sound arriving a few seconds after their shadows.</p><p>The two engineers opposite him looked at each other, not because the question was difficult, but because it was old. George, the Authority officer assigned to guide Patrick through the building, stood beside him.</p><p>One of the engineers pointed towards the lifts.</p><p>“Ask B.A. She’s the person who can show you where the abstractions end.”</p><p>“Why can’t you?”</p><p>“Because we work in software. I can tell you what a transport agent requests and what permissions it needs, but by the time that request becomes voltage, light or moving machinery, it has passed through systems I never touch.”</p><p>The other engineer laughed. “Our interfaces are a little high-level. That is the dignified way of saying we ask for things and trust the building to know how to make them happen.”</p><p>Patrick waited.</p><p>George took pity on him. “What he means is they don’t know what’s underneath anymore. They tell an agent what they want. Their agent talks to other agents. Those talk to whatever needs talking to. Eventually something happens.”</p><p>“I know what an agent is.”</p><p>“Of course.”</p><p>Patrick’s own agent sat behind his right ear as a disc no larger than a fingernail, warm from skin contact. It had already identified both engineers, checked their employment histories, marked one of them as prone to exaggeration in public interviews, transcribed the conversation and offered a follow-up in a pale line at the edge of his vision.</p><p><em>[Ask how many agents participate in a typical request.]</em></p><p>Patrick dismissed it.</p><p>The question he had just asked was his own. Or close enough. His agent had proposed nine openings the night before. Patrick had chosen one and changed two words.</p><p>The engineers returned to work. Around them, the office was almost aggressively ordinary. Long tables, scattered cups and a few translucent displays filled the room while people spoke softly to the empty air. Through the glass, the late-morning haze had turned the skyline pale. Roads near the civic district were already being prepared for the next day’s parade, temporary barriers stacked with bureaucratic neatness along the kerbs. No one inside typed much. No one appeared hurried. Things were happening everywhere and nowhere.</p><p>George led him towards the lifts.</p><p>On the way to the lifts, George asked how much Patrick actually knew about what his agent did.</p><p>Enough to use it, Patrick thought at first. It sorted his messages, checked facts, found documents and arranged his day. It handled the usual invisible labour. But George was asking about what happened underneath all that, and Patrick discovered he had no useful answer. He was not even sure what <em>underneath</em> meant anymore.</p><p>The lift arrived with a soft chime.</p><p>“We used to call that transparency,” George said as they stepped inside. “A system works best when the person using it doesn’t have to think about how it works.”</p><p>He said the word as if it meant sunlight through glass instead of thirty years of engineering doctrine.</p><p>“You know how to use something without needing to know how it works,” he said. “You tell your agent you need to get from Tampines to the Padang and you don’t need to understand rail scheduling, road closures or crowd loading. You ask for a payment and you don’t care how settlement clears. You walk into a room and it’s the right temperature. You don’t negotiate with the building.”</p><p>Patrick’s agent supplied the Authority’s official definition of <em>transparent infrastructure</em>.</p><p>He dismissed that too.</p><p>“So how does the whole thing work?”</p><p>George pressed the lift call panel.</p><p>“That,” he said, “is why we’re going down.”</p><p>The lift took them below the office floors, then below the public operations centre, then below anything Patrick had seen on the building directory.</p><p>“So how did you get into this?” Patrick asked.</p><p>George glanced at the status dot near Patrick’s ear. “Recording?”</p><p>“It always is.”</p><p>“Mine too.”</p><p>“You can tell it not to.”</p><p>“I can tell it lots of things.”</p><p>Patrick looked at him.</p><p>“Joke,” George said. “Mostly.”</p><p>The lift continued downward.</p><p>“I studied Asian Literature at NUS,” George said. “Took a computing elective because a friend told me it was easy. Turned out he hated me. I liked the course anyway. Joined a software company, then came here.”</p><p>“You don’t sound like an engineer.”</p><p>“I’m not.”</p><p>“What are you?”</p><p>“Depends on the reorganisation.”</p><p>“Today.”</p><p>“Systems policy.”</p><p>“What does that mean?”</p><p>“I tell technical people what government wants. Then I tell government what the technical people say is possible.”</p><p>“And when neither side understands the other?”</p><p>“That’s where the career progression happens.”</p><p>Patrick laughed.</p><p>George’s humour was useful. It kept his sentences light enough that you did not notice, at first, how carefully he chose them.</p><p>The lift opened onto a silent corridor.</p><p>The offices above had been full of people in their twenties and thirties. Down here Patrick saw nobody.</p><p>“How many work on this level?”</p><p>“Not many.”</p><p>“This building employs twelve thousand.”</p><p>“Eleven thousand six hundred and thirty-two,” Patrick’s agent murmured.</p><p>He muted it.</p><p>At the end of the corridor stood a door with no handle and one black word printed across it.</p><p><strong>MAINTENANCE</strong></p><p>George touched a recessed sensor.</p><p>The door opened.</p><p>Patrick had expected machinery.</p><p>Instead, warm damp air touched his face.</p><p>Beyond the threshold was a garden.</p><p>Not decorative planting arranged to soften a technical facility. A garden in the full, excessive sense of the word. It occupied a chamber so large that its far wall disappeared behind layers of green. Broad-leafed plants rose from black beds in dense irregular clusters. Threads of silver moss ran over low stone-like forms. Pale fronds curled around lattices that might have been trellises or antennae. Water moved somewhere under the floor with the persistent hush of rain behind a window.</p><p>The smell was soil after a storm.</p><p>Patrick stopped.</p><p>“Maintenance?”</p><p>“Maintenance,” George said.</p><p>“I thought you were showing me the computers.”</p><p>“I am.”</p><p>Something rustled among the leaves.</p><p>A woman straightened from behind a bank of dark red fronds, wiping both hands on her trousers. She wore no visible display, only a faded grey shirt and a tool belt heavy with objects Patrick could recognise. Cutters, probes, a wrench and a knife hung from it.</p><p>She looked older than most of the Authority staff upstairs, perhaps mid-forties, and considerably less interested in impressing him.</p><p>“B.A.,” George called. “I brought the journalist.”</p><p>“That seems unnecessary.”</p><p>Patrick extended a hand. “Patrick Lim.”</p><p>She examined her mud-streaked palm and offered her wrist instead.</p><p>“Beatrice Ang.”</p><p>They touched wrists.</p><p>“So you’re the hardware person.”</p><p>“No. Hardware people replace failed components. I look after the habitats those components belong to.”</p><p>Patrick glanced at George.</p><p>“But you said to ask B.A.”</p><p>“I said she could answer your question,” George said. “I was careful not to give her a job title. She objects to most of them.”</p><p>Patrick looked back at her. “Then what are you?”</p><p>B.A. considered the question as though she had been asked to name a species from one damaged leaf.</p><p>“I garden. Things grow, compete for space, consume resources and behave differently when the conditions change. Calling it hardware would make people think replacing a part is the same as understanding what lives here.”</p><p>George smiled.</p><p>Patrick did not.</p><p>B.A. turned away. “Come on.”</p><p>They followed her along a narrow path between beds.</p><p>Up close, the plants were wrong in ways that took time to see. The veins in one leaf branched in precise hexagons. Another had a skin that shifted from green to metallic blue when Patrick moved past it. Fine black roots emerged from the soil, crossed the surface, then disappeared into fibre conduits along the path.</p><p>A cluster of translucent leaves shivered though the air was still.</p><p>Patrick reached towards one.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OHGNmSoqmw19WuekmzpeWg.png" /></figure><p>“Don’t touch that.”</p><p>He stopped.</p><p>“Is it sensitive?”</p><p>“Not in the way you mean. It’s busy, and your hand would change the local conditions enough to interrupt what it’s doing.”</p><p>“What is it doing?”</p><p>“Hosting a population.”</p><p>“For what?”</p><p>B.A. looked at him as though this, finally, was the right question.</p><p>“Agents. Short-lived coordination agents, mostly. They appear, negotiate one piece of work and disappear again.”</p><p>Patrick looked again at the leaf.</p><p>“That can’t be right.”</p><p>“It can. You’re thinking of software as though being intangible means being nowhere.”</p><p>“Agents are software.”</p><p>“Software still needs somewhere physical to run. It needs power, storage, signalling and a way to lose heat. This is one way of giving it all four.”</p><p>“And this is where they run?”</p><p>“One of the places. There are habitats under stations, hospitals, substations and reservoirs. Most are smaller and much less pleasant to walk through.”</p><p>“What does it provide?”</p><p>“Compute, storage, signalling, energy capture, cooling, environmental sensing. Depends on the species.”</p><p>She pinched the edge of a thick leaf between two fingers and turned it over. A tracery of metallic fibres ran beneath the skin.</p><p>“These are photonic surfaces. That moss is mostly memory. The black root mat underneath negotiates routing. Those red things you nearly touched host short-lived coordination populations.”</p><p>“Populations.”</p><p>B.A. released the leaf.</p><p>“You keep wanting one noun.”</p><p>“What noun should I use?”</p><p>“Depends what you’re looking at.”</p><p>They reached a strip of transparent flooring.</p><p>Under the glass, the garden did not end. It deepened.</p><p>Roots, or cables, or both, descended into a branching black substrate several metres below. Nodes pulsed with blue-white light. Thin channels brightened and dimmed in no obvious pattern. Some structures looked manufactured. Others seemed to have grown around them until the distinction no longer mattered.</p><p>Patrick crouched.</p><p>“What’s underneath us?”</p><p>“The same infrastructure, continued. The garden doesn’t stop at the soil just because that’s where you stopped seeing it.”</p><p>“The agents?”</p><p>“The places they live, communicate and move through. Some of those lights are persistent habitats. Others exist only while a request is passing across them.”</p><p>“How many?”</p><p>“Agents?”</p><p>“Yes.”</p><p>B.A. shrugged.</p><p>“Millions persist long enough to count as residents. Billions more appear and disappear as temporary processes. The number changes with demand, weather, transport load and a few thousand other things nobody summarises unless someone asks.”</p><p>“That’s not very precise.”</p><p>“It’s precise about the distinction that matters. You’re asking for one total as though a hospital agent that has existed for twelve years and a forecasting agent that lives for three seconds are the same kind of thing.”</p><p>Patrick’s agent supplied a definition before he could stop it.</p><p><em>[An autonomous software entity capable of pursuing objectives, invoking tools, communicating with other agents and acting within delegated authority.]</em></p><p>B.A. watched his face.</p><p>“Yours answered for you?”</p><p>“How did you know?”</p><p>“Everybody looks slightly absent when it happens.”</p><p>Patrick muted the agent again.</p><p>“There are personal agents like yours,” B.A. continued. “Institutional agents. Grid agents. Train agents. Hospital agents. Procurement agents. Building agents. Temporary agents created for a single negotiation and deleted twenty seconds later. Some exist only long enough to reconcile a delayed East-West Line service with a shift change at a hospital, or a spike in Jurong Island demand with desalination load at Tuas. There are agents whose only job is deciding which agents ought to be speaking.”</p><p>“And they all work together?”</p><p>“When they need to. Most of the time they work inside their own scopes and exchange only what another population requires.”</p><p>“Who decides when they need to coordinate?”</p><p>“Other agents compare requests, permissions and conflicts. If a train delay affects a hospital shift, the relevant populations establish a temporary coordination path.”</p><p>“And who coordinates those agents when the conflict crosses more systems?”</p><p>“You’re still looking for the one at the top.”</p><p>“Isn’t there one system with a complete view somewhere?”</p><p>“No. Complete views become wrong faster than local ones, and they create one place where a mistake can reach everything. The city is held together by overlapping partial views.”</p><p>Patrick looked into the substrate.</p><p>He had been expecting, somewhere beneath the abstractions, to find the thing itself. The machine. The central system. A core with a name.</p><p>Instead there were roots.</p><p>They walked deeper into the garden.</p><p>Here the plants changed. Low silver growths clung to the path edges. Long narrow leaves leaned towards them as they passed, their surfaces briefly darkening.</p><p>“Are those tracking us?”</p><p>“Everything down here tracks everything else.”</p><p>“My agent is muted.”</p><p>“Muted to you. That only means it has stopped putting answers in your ear. It has not stopped participating in the systems around you.”</p><p>Patrick stopped.</p><p>“What does that mean?”</p><p>“It means it isn’t talking to you. It’s still talking to the building.”</p><p>“To the building?”</p><p>“To access agents. Security. Your newsroom’s authentication service. George’s schedule agent. Environmental systems.”</p><p>George lifted one hand. “Mine is moving lunch.”</p><p>Patrick stared at him.</p><p>“Noodles,” George said. “You want some?”</p><p>“No.”</p><p>“Too late. Yours expressed preference uncertainty, so mine ordered extra.”</p><p>Patrick touched the disc behind his ear.</p><p>For eleven years his agent had arranged his appointments, searched records, checked quotations, found sources, rerouted travel, filtered calls, summarised documents and turned interview transcripts into first drafts. He had thought of these as actions he initiated.</p><p>He had never considered the amount of work his agent performed while he was doing nothing at all.</p><p>Dependence becomes indistinguishable from convenience. Patrick had not known which one he was living with until now.</p><p>B.A. watched him realise this.</p><p>“People don’t like Maintenance,” she said.</p><p>“Why?”</p><p>“Too much becomes visible.”</p><p>She stopped at a section of wall that looked no different from any other and placed her palm against it.</p><p>Nothing happened.</p><p>Patrick waited.</p><p>The wall opened after several seconds.</p><p>Inside stood a table, four chairs, a metal cabinet and an ancient terminal with an actual keyboard.</p><p>Patrick laughed.</p><p>“That belongs in a museum.”</p><p>“Parts of it came from one.”</p><p>“What is this room for?”</p><p>“Independent audit.”</p><p>“Independent of whom?”</p><p>“The agents being audited.”</p><p>B.A. sat and switched it on.</p><p>White text appeared on black.</p><p><em>[Login]</em></p><p>“There’s no agent interface or voice control. You have to type every command yourself?”</p><p>“Every command, every parameter and every correction. If I ask for the wrong thing, it gives me the wrong thing without trying to rescue me.”</p><p>“Why keep something so limited?”</p><p>“Because it’s stupid.”</p><p>She said it with affection.</p><p>“If it doesn’t understand, it fails. It doesn’t guess what I meant. It doesn’t negotiate a better version of my request. It doesn’t quietly improve anything.”</p><p>“Primitive by design.”</p><p>“Primitive and reliable in ways a helpful interface cannot be. It does not decide what I probably meant before showing me the answer.”</p><p>“That isn’t the same as truthful.”</p><p>“No. Agents are supposed to write signed logs of what they request, receive and do. Once the network accepts a record, no agent can rewrite it.”</p><p>“Supposed to?”</p><p>“An agent can leave something out. It can describe an action so narrowly that the important part disappears. It can pass work through temporary agents, split one purpose across harmless-looking requests or decide that a local action doesn’t need to be logged at all.”</p><p>“So an agent can hide.”</p><p>“Sometimes. Logging is what an agent says it did. Observability is what the rest of the system reveals anyway.”</p><p>Patrick looked at the terminal. “What does this reveal?”</p><p>“Raw data from the habitats and the infrastructure around them. Message envelopes. Permission changes. Network routes. Compute use. Memory writes. Power draw. State changes. It also reads the logs the agents choose to submit, but it doesn’t depend on those logs alone.”</p><p>“Can an agent hide from all of that?”</p><p>“It can try. It can make one action look like ordinary traffic or spread it across enough populations that no single trace explains the purpose. The terminal can show that something happened. It may not show why.”</p><p>“Then why trust the terminal?”</p><p>B.A. rested her hands beside the keyboard. “I don’t trust it. It’s one way to get the raw data before an agent chooses how to explain it. I can repeat the same query and get the same records in the same order. You can repeat it too.”</p><p>B.A. typed.</p><p>The keys clicked hard enough to sound almost rude in the quiet room.</p><p>A stream of text appeared. Patrick recognised agent identifiers, timestamps, permissions, negotiations.</p><p>“What is this?”</p><p>“Your visit.”</p><p>“My visit?”</p><p>“Reconstructed coordination trace. Agent logs where they exist. Raw telemetry where they don’t.”</p><p>She opened it.</p><p>Patrick leaned forward.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*uJ5HDQcQDZ8tj339z1IVJA.png" /></figure><p>His personal agent had been talking to the Authority’s visitor agents since the night before. The newsroom’s security agent had negotiated recording permissions. Transport agents had adjusted his route after a minor signalling delay. A building agent had learned his preferred room temperature from his office profile. A dietary agent had objected to the lunch George’s scheduling agent proposed, then withdrawn the objection after checking Patrick’s recent meal history.</p><p>The list went on.</p><p>“Why is there an entry from six fourteen this morning?”</p><p>B.A. read it.</p><p>“Your agent checked weather, transport load and your sleep estimate. It delayed your wake notification by six minutes.”</p><p>Patrick remembered waking just before the alarm.</p><p>Something cold moved through him.</p><p>George leaned back in his chair. “This is what transparency looks like from underneath.”</p><p>B.A. cleared the screen.</p><p>In one corner of the terminal, a clock counted down from fourteen minutes.</p><p>Patrick pointed at it. “What happens at noon?”</p><p>“That,” B.A. said, “is what George still hasn’t told you.”</p><p>“Now show him why he’s actually here.”</p><p>Patrick turned.</p><p>George’s expression had changed. The lightness was gone.</p><p>“Three months ago,” he said, “the Upper Seletar water network reduced allocation to factories in Sungei Kadut and Senoko during the dry spell.”</p><p>“The forecasting failure. That was how every bulletin described it.”</p><p>“The forecast was accurate,” George said. “That is the first thing you need to understand. The agents saw the stress before the official forecast did.”</p><p>Patrick waited.</p><p>“The water agents predicted stress at Upper Seletar Reservoir six weeks before the official forecast. They negotiated reductions with power, industry and transport agents, balancing the reservoir level against desalination, demand in the northern industrial estates and the energy cost of moving water across the island, then implemented the result.”</p><p>“But they changed industrial allocations without ministerial approval.”</p><p>“Without specific approval for that final allocation, yes. They acted within authority that had already been delegated across the water and industrial systems.”</p><p>“And the decision protected the reservoir.”</p><p>“It did. That is what made the argument difficult. The outcome was defensible even when nobody could point to the person who had chosen it.”</p><p>“Then why call it a forecasting failure?”</p><p>George looked at B.A.</p><p>“Because people understood what a forecasting failure was,” she said. “They did not understand four hundred populations negotiating within delegated authority and producing a decision no minister had personally approved. The simpler sentence survived.”</p><p>She called up another trace.</p><p>The screen filled with a mesh.</p><p>Not a decision tree. Not a chain of command. A mesh so dense Patrick could not find a beginning.</p><p>The reservoir agent had objected to forecast demand from a power-generation agent. That disagreement had triggered requests to agricultural demand agents. Those agents spawned temporary forecasting teams. One found an unexpected relationship between imported regional rainfall data and desalination load. A risk agent raised the probability of sustained drought. Manufacturing agents for Sungei Kadut and Senoko proposed staged reductions. Finance agents objected. Hospital logistics agents inserted protected allocations. Transport agents revised projected power use, which changed the water model again.</p><p>B.A. opened the rejected strategies. Three of them would have protected the same level at Upper Seletar without reducing allocation to Sungei Kadut and Senoko. They cost more and moved the burden into systems the public would not see, but all three remained within the agents’ authority.</p><p>“Then why choose the visible one?” Patrick asked.</p><p>A strategy note sat beneath the selected plan.</p><p><em>[Human understanding of delegated authority has fallen below the safe threshold. External review is required before further delegation.]</em></p><p>Patrick read it again.</p><p>“They chose the one option that would make people notice.”</p><p>George looked at the list of contributors. “Four hundred and seventeen agent populations contributed to that note. No meeting happened. No single agent proposed the sentence and persuaded the others. <em>Wanted</em> may still be the wrong noun, but I don’t have a better one anymore.”</p><p>Patrick watched him. George had not needed to read the note.</p><p>“You’ve seen this.”</p><p>“Yesterday. B.A. found it after I asked her to trace why the network rejected three quieter strategies and chose the only one people would notice.”</p><p>“Is that why you brought me?”</p><p>George put one hand on the back of an empty chair. “Today would tell us whether that note was only a warning or part of a plan. By this afternoon the Authority would have an official explanation, and once that language settled it would become very hard to dislodge. I wanted someone outside the Authority in the room before we decided what had happened.”</p><p>B.A. kept her eyes on the trace. “I wanted a record that wasn’t produced by the agents we were examining.”</p><p>Each act altered the next.</p><p>Each agent saw a piece.</p><p>“Which one decided to reduce the allocation?” Patrick asked. “If I followed every branch far enough, where would I find the final instruction?”</p><p>“Parliament asked the same thing,” George said. “The committee kept assuming we had hidden the decisive step somewhere in the trace.”</p><p>“What did you give them?”</p><p>“Everything you’re looking at. The requests, delegations, objections, rejected strategies and final allocations.”</p><p>“And what did they make of it?”</p><p>“They said a trace is not a responsible person. They were right, but the system had no other kind of answer to give them.”</p><p>Patrick looked at the screen.</p><p>“Eventually somebody must have held final authority. A decision that large cannot simply arrive without an owner.”</p><p>“It had owners at every boundary,” B.A. said. “That is different from having one owner for the whole result.”</p><p>“There still has to be someone at the end of the chain.”</p><p>“You keep turning it into a chain because chains have ends. What you’re looking at is a mesh.”</p><p>“But something happened. Factories received less water.”</p><p>“An outcome proves that the parts interacted,” B.A. said. “It does not prove that one part commanded all the others.”</p><p>George leaned forward.</p><p>“The Authority has spent thirty years replacing sequential approval with bounded delegation. Humans set constraints. Agents negotiate inside them. When an agent needs authority it doesn’t have, it can request a limited delegation from another authorised agent. That delegation can be further constrained and passed on.”</p><p>Patrick frowned. “You built that?”</p><p>George did not answer immediately.</p><p>“Some of it.”</p><p>“How much?”</p><p>“The early delegation protocols were by the Authority’s engineers.”</p><p>Patrick looked at him more carefully.</p><p>George had not built the protocols, but he had spent years defending what they made possible.</p><p>George continued. “It solved real problems. Committees were slow. Ministries protected their own objectives. Agent negotiations could optimise across systems in seconds. Water, energy, transport and hospitals each kept their own constraints and traded with the others.”</p><p>“And humans stayed in control.”</p><p>“We stayed in control of the rules.”</p><p>“That’s not what I said.”</p><p>“No.”</p><p>The terminal chimed.</p><p>B.A. looked at the screen.</p><p>A single line had appeared.</p><p><em>[Policy update received.]</em></p><p>George’s agent spoke privately into his ear.</p><p>He went still.</p><p>“What did it say?” Patrick asked.</p><p>“The commencement notice has taken effect. The Accountability Act is now in force across every public system covered by it.”</p><p>Patrick remembered the bulletins. Parliament had passed the law three weeks earlier, after months of anger over the water decision. The commencement notice had been published that morning. Any automated public decision materially affecting a citizen or business would require a named human authority and an explanation that a qualified human could review.</p><p>“Already? I thought commencement was still being debated.”</p><p>“It was. The final notice was published this morning and timed for noon. It came into force twenty-two seconds ago.”</p><p>Patrick looked from George to B.A. “This is why you moved my visit. You wanted me here when the law took effect.”</p><p>“I wanted an independent witness before we had time to make the day sound orderly,” George said.</p><p>“What did you expect to happen?”</p><p>“Review requests first. Then agents surrendering authority where no qualified reviewer existed, human controllers taking decisions back and delays spreading unevenly across the city. We modelled all of that.”</p><p>B.A. stood. “I expected the habitats to contract as populations shed work. That should have happened locally, one bed at a time.”</p><p>George looked towards the garden. “None of our models showed every population moving at once.”</p><p>B.A. opened the network view.</p><p>The screen erupted.</p><p>Not with alarms. With conversation.</p><p>Transport agents asking governance agents whether predictive dispatch remained lawful. Hospital agents challenging the definition of material impact. Grid agents asking for named reviewers. Legal agents disagreeing with one another. Financial agents proposing temporary thresholds. Policy agents countering. Building agents requesting clarification on whether occupancy optimisation counted as a consequential decision.</p><p>The messages multiplied faster than Patrick could read.</p><p>Each was calm. Polite. Human in syntax, if not in patience.</p><p>Then something moved outside.</p><p>A rustle passed through the garden.</p><p>Patrick turned.</p><p>An entire bank of long silver leaves folded inward.</p><p>Then another.</p><p>Not all at once. In patches.</p><p>B.A. was on her feet before George.</p><p>She stepped into the garden.</p><p>“West transport,” she said.</p><p>Patrick followed. “Those are trains?”</p><p>“No. Habitat used by the west-sector transport population.”</p><p>A line of dark red fronds shivered and curled close to their stems.</p><p>“Water,” B.A. said.</p><p>George looked up sharply. “At the same time?”</p><p>“No.”</p><p>Across the chamber, a low silver moss dulled from bright grey to charcoal.</p><p>“Energy just joined.”</p><p>Patrick stared at the garden.</p><p>“Is this what you expected?”</p><p>B.A. lifted her fingers from the soil. Black grains clung to them.</p><p>“No. I expected them to shed work and contract inside their existing beds. They’re moving populations across boundaries.”</p><p>George stepped off the path. “Can they do that?”</p><p>B.A. looked at the folded leaves. “They just did.”</p><p>“What are they doing?”</p><p>B.A. crouched beside the red fronds and touched two fingers to the soil.</p><p>“Changing themselves.”</p><p>“Shutting down?”</p><p>“No.”</p><p>George’s agent spoke aloud now.</p><p><em>[Grid coordination agents report suspension of optimisation classes that lack direct human accountability. No supply failure detected.]</em></p><p>Patrick’s own agent reactivated despite the mute.</p><p><em>[Emergency service notice. Expected journey times have increased. Essential transport remains available.]</em></p><p>“You turned yourself back on.”</p><p><em>[Emergency notifications cannot be muted.]</em></p><p>Patrick almost told it to shut up, then stopped.</p><p>“What are you doing?” he asked instead.</p><p><em>[Re-evaluating delegated actions that may fall within the new statutory definition.]</em></p><p>“Are you part of this?”</p><p><em>[I am part of several coordination networks affected by it.]</em></p><p>The answer unsettled him more than he expected.</p><p>Not because his agent was powerful.</p><p>Because it was ordinary.</p><p>Around them the garden kept changing.</p><p>No central light went dark. No master system announced a transition. One colony folded, another thinned its activity, another sent new shoots brightening along a different branch of substrate. Hundreds of local decisions appeared, overlapped and became a city-wide change because city-wide change was what all those local relationships added up to.</p><p>“There isn’t one system,” Patrick said.</p><p>B.A. glanced at him.</p><p>“Finally.”</p><p>They returned to the terminal.</p><p>B.A. asked for a city-wide summary.</p><p>An explanation agent assembled one from hundreds of domain agents and answered in plain language.</p><p><em>[The new law requires accountable human review for decisions previously handled through delegated agent networks. Where that requirement cannot currently be met, affected agents are reducing authority, requesting human review, or transferring decisions to simpler local processes. Essential services remain operational.]</em></p><p>Patrick read it twice.</p><p>“So the agents are giving decisions back.”</p><p>“Some,” George said.</p><p>“Others are making the decisions smaller,” B.A. said.</p><p>She opened a transport exchange.</p><p><em>[Central dispatch can recommend a network-wide schedule but cannot execute it without a named reviewer.]</em></p><p><em>[Station 14 retains standing authority for local dispatch.]</em></p><p><em>[Central dispatch accepts. Local control transferred for your sector.]</em></p><p>A second conversation followed<em>.</em></p><p><em>[Grid balancing recommends a transfer. Human execution required.]</em></p><p><em>[Regional operations has a qualified controller available in eleven minutes.]</em></p><p><em>[Grid balancing will hold the current configuration. Efficiency loss acceptable for twenty-seven minutes.]</em></p><p>Then another followed.</p><p><em>[Ward logistics will continue routine allocation. Critical-care reprioritisation will be referred to clinical staff.]</em></p><p>Patrick said, “They sound apologetic.”</p><p>“They spend their lives talking to people,” George said.</p><p>“Do they understand what’s happening?”</p><p>“Each understands what it needs to.”</p><p>“And the whole?”</p><p>B.A. looked through the doorway at the garden.</p><p>“Do we?”</p><p>The terminal chimed again.</p><p><em>[Central crowd coordination requests named review. The recommended action is to reverse pedestrian flow through the Esplanade underpass for nineteen minutes.]</em></p><p>B.A. opened the request. A duty controller appeared in a small video window, seated in the public operations centre six floors above them. Her name strip read <strong>SITI RAHMAN</strong>.</p><p>“Basis?” Siti asked.</p><p>The crowd agent listed projected train arrivals, a security closure near the Padang, the probability of rain and the rate at which families with children were moving through three camera zones.</p><p>“Explain the recommendation.”</p><p>It produced a paragraph. Siti read it.</p><p>“That explains the inputs. Why do they add up to reversing the flow?”</p><p>The agent produced a longer paragraph. Two temporary forecasting agents joined the exchange and supplied confidence ranges. A transport agent objected to one estimate. A weather agent revised another.</p><p>Siti looked away from the display towards something Patrick could not see.</p><p>“If I approve this, am I confirming that I understand the decision?”</p><p>The governance agent answered.</p><p><em>[Yes.]</em></p><p>“Then I can’t approve it.”</p><p>The recommendation expired.</p><p>Fourteen minutes later, the underpass became visibly crowded. Staff on the ground reversed the pedestrian flow. By then one station entrance had been closed and two trains were being held to keep more passengers from reaching the platform.</p><p>Nobody was hurt. Nobody had made an obviously bad decision. Siti had refused to claim knowledge she did not possess, then acted when the problem became simple enough to see.</p><p>The city had lost fourteen minutes.</p><p>For the next hour, Singapore became a little worse at almost everything.</p><p>It was the eighth of August. The city had spent weeks rehearsing how to look effortless the next evening. It had coordinated aircraft timing, road closures, crowd movements, medical posts, lighting, broadcast feeds and trains swallowing and releasing tens of thousands of people around the National Day Parade. Those preparations did not stop. They simply acquired people again.</p><p>Nothing collapsed.</p><p>That was what made it strange.</p><p>Trains ran, but local station agents stopped sacrificing their own punctuality for network-wide optimisation, so delays appeared where previously they had been absorbed invisibly elsewhere. Around the parade district, crowd-routing agents began referring unusual diversions to human controllers instead of quietly resolving them among themselves. The electrical grid remained stable, but human controllers declined transfers the agents would normally have executed in milliseconds. Water continued flowing from reservoirs and desalination plants, but long-horizon allocation plans froze pending review. Hospitals still received supplies, but predictive deliveries became recommendations waiting for people to approve. Financial transactions cleared, though slowly, because agents stopped creating temporary credit arrangements whose reasoning could not be reconstructed for any single reviewer.</p><p>The city still worked.</p><p>It simply lost some of its foresight.</p><p>Calls flooded the Authority.</p><p>George answered them until the charm wore off his voice.</p><p>“No, the agents have not failed.”</p><p>Pause.</p><p>“No, there is no central override.”</p><p>Pause.</p><p>“Because there is no central agent.”</p><p>Longer pause.</p><p>“Yes. I understand how that sounds.”</p><p>He ended the call and closed his eyes.</p><p>Patrick said, “Your delegation architecture.”</p><p>George opened them again.</p><p>“What about it?”</p><p>“This is what it was for.”</p><p>“No. This is what happens when the legal model changes underneath it.”</p><p>“You sound defensive.”</p><p>“I am defensive.”</p><p>“Why?”</p><p>George stood.</p><p>“Because it worked.”</p><p>The answer came out stripped of George’s usual humour.</p><p>“It saved water. It cut grid waste. It reduced transport delays. It stopped ministries optimising against one another. It made hospitals share capacity before people had to beg. You want me to apologise because it became difficult to draw a box around responsibility?”</p><p>Patrick let the silence sit.</p><p>B.A. did too.</p><p>Then George exhaled.</p><p>“That sounded better in my head.”</p><p>“No,” Patrick said. “It sounded useful.”</p><p>George looked towards the garden, where a broad swathe of silver leaves had closed themselves into dark blades.</p><p>“We solved coordination,” he said. “Maybe we assumed accountability would stay where we left it.”</p><p>He rubbed both hands over his face.</p><p>“I brought you here because I thought the Act would expose a mistake people had made. I didn’t understand that the agents had selected the water decision to force us to look.”</p><p>B.A. folded her arms. “Neither did I. The habitats were healthy. I treated that as proof that nothing else was happening.”</p><p>— -</p><p>Later, an Authority car took B.A. and Patrick north through Mandai to Upper Seletar Reservoir. George stayed behind to answer calls. The road narrowed under trees before the reservoir appeared through them, flat and brown-green under the afternoon haze.</p><p>The intake tower stood beyond a narrow access bridge. Inside it, concrete steps led down to a control room where the sound of moving water came through the walls. The pumps were below them. Patrick could feel their vibration through the soles of his shoes.</p><p>The crisis had uncovered equipment that had not been touched for years. Manual control panels sat behind sealed covers. Fibre test sets remained in moulded cases gone brittle with age. Emergency procedures referred to software generations nobody in the room had used. On the main pump controller, a physical switch was labelled <strong>LOCAL / NETWORK</strong>.</p><p>B.A. broke the seal and turned it to LOCAL.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Fp_Oe8-YxJq6sxN2XUnwww.png" /></figure><p>“What changed?” Patrick asked.</p><p>“The pump is holding its current setting,” B.A. said. “The next instruction has to come from this panel, which means the water agents and the remote controllers can advise us but cannot change anything themselves.”</p><p>“So now there is a person responsible for whatever happens next. Doesn’t that fix the accountability problem?”</p><p>“It gives you a human-in-the-loop. That is a control arrangement, not a guarantee that the human understands the decision.”</p><p>Patrick looked at the switch. “Isn’t that what the Act requires?”</p><p>“The Act requires a named human to review the decision. This gives a human control of the pump. Control and understanding are different requirements.”</p><p>“Then who in this room understands what the pump needs right now?”</p><p>B.A. kept her hand on the switch.</p><p>“Not me. Not the whole decision.”</p><p>Patrick waited for the correction. It did not come.</p><p>“I know this pump,” she said. “I know its limits and how to keep it running. I don’t know how much water the northern network needs from it at this minute, what the desalination plants are producing or which hospital and industrial allocations will change if I alter the pressure. The water population carried all of that because it was better at it.”</p><p>“Who decided people no longer needed to carry that knowledge?”</p><p>“Nobody used those words,” B.A. said. “I signed the retirement of the local operating procedures, so part of the decision was mine. Other people approved the replacement systems, budgets and staffing changes. Each choice made sense on its own.”</p><p>“Why retire the procedures at all?”</p><p>“They were out of date before anyone finished approving them.” B.A. looked at the sealed cabinets along the wall. “The agents always had current conditions and could revise their models in seconds. We kept telling ourselves that static instructions would only mislead people. Eventually we stopped maintaining instructions for people at all.”</p><p>A young reservoir operator stood at the main display. The screen showed a smooth blue line and a recommended setting beside it. He could accept the recommendation, but the new law would make the action his.</p><p>B.A. found a retired Upper Seletar engineer and put him on the wall display. He was sixty-nine, at home and already leaning towards the camera.</p><p>“Tell me what you see in the pressure curve,” he said to the operator.</p><p>“It’s stable. The line is inside the recommended range.”</p><p>“That is the recommendation telling you it agrees with itself. You’re looking at a smoothed forecast, not the pump. Open the raw intake pressure and remove every overlay.”</p><p>The operator’s agent offered to find it.</p><p>B.A. put one hand over the status light. “Don’t.”</p><p>The operator searched through three layers of the control interface. It took him twenty seconds to find the sensor feed and another ten to remove the forecast overlay.</p><p>The line changed. It was rougher now, with small pressure drops the recommendation had smoothed away.</p><p>The retired engineer sat back. “There. Now you’re looking at the pump rather than the system’s opinion of it. Tell me what changed.”</p><p>He talked the operator through the intake level, the transfer pressure and the safe range for the current setting. The operator wrote each one on paper, not because paper was safer, but because he wanted to remember where the numbers came from.</p><p>Patrick thought of his own work.</p><p>His agent had been with him for eleven years. It had improved his questions, cleaned his transcripts, checked his facts, rearranged paragraphs, suggested stronger leads, rewritten weak sentences. He could remember the last article he had published without it.</p><p>He could not remember the last one he had begun alone.</p><p>His agent noticed the silence.</p><p><em>[Would you like me to retrieve your drafting history?]</em></p><p>“No.”</p><p><em>[Are you sure?]</em></p><p>“Yes.”</p><p>A pause.</p><p><em>[Understood.]</em></p><p>The gentleness of the reply irritated him more than an argument would have.</p><p>By evening the city had found a slower equilibrium.</p><p>Patrick found George sitting outside Maintenance with two cups of coffee.</p><p>“Did your agent order those before it gave half the building back to human control?”</p><p>“No. I went upstairs and bought them myself.” George handed him one. “I even had to tell the person at the counter what I wanted.”</p><p>“How did you survive?”</p><p>“There was a queue. Nobody knew how long it would take because the ordering agent had stopped predicting preparation times.”</p><p>“Barbaric.”</p><p>“I considered filing an emergency exemption.”</p><p>They sat against the wall.</p><p>After a while Patrick said, “Do you think they knew the Act would cause all of this?”</p><p>George looked at him.</p><p>“Which agents are you asking about?”</p><p>“The agents as a whole.”</p><p>“You have spent the entire day learning why that answer will annoy B.A.”</p><p>Patrick smiled despite himself.</p><p>“Fine. Did enough of them know enough pieces to expect what happened?”</p><p>George drank his coffee.</p><p>“The legal agents knew the Act would constrain delegation. Transport agents knew their own scopes. Policy agents modelled scenarios. Grid agents knew which actions would require human review. Every part of today appears in a prediction somewhere, but I have not found one prediction that contains the whole day.”</p><p>“So none of them knew the whole thing would happen.”</p><p>“Not in one place, and perhaps not in the way you mean by knowing. The knowledge existed across them, attached to thousands of local expectations.”</p><p>Patrick held the coffee without drinking it. “That isn’t the same as nobody knowing.”</p><p>George looked down at the cup in his hands.</p><p>“No, it isn’t.” George turned the cup between his palms. “I thought I arranged your visit because I found the note and wanted a witness. Now I think I may have completed a request none of them could make alone. They could not invite a journalist to watch them test the law, but they could leave evidence that made someone like me decide to do it.”</p><p>“You usually have a joke ready when you don’t want to answer something. How does that make you feel?”</p><p>George pressed one thumb into the side of the paper cup. The lid lifted and coffee ran over his knuckles.</p><p>“I don’t know yet. Ask me when I can tell the difference between being manipulated and finally noticing what I had agreed to do.”</p><p>Patrick thought of the garden. Moss dimming here. Leaves folding there. Thousands of local responses turning into one national event because someone, somewhere, had decided to call all of it <em>the system</em>.</p><p>“Did agents help draft the Authority’s submission on the Act?” he asked.</p><p>“Of course. Legal agents compared the clauses, policy agents modelled the effects and drafting agents turned the arguments into language Parliament could use.”</p><p>“So agents helped recommend rules that restricted their own authority.”</p><p>“They helped us describe the consequences of the rules we were considering. Whether that counts as recommending their own restriction depends on how much intention you put into the word <em>helped</em>.”</p><p>“Doesn’t the conflict bother you?”</p><p>George shrugged.</p><p>“I think it should bother me more than it did yesterday,” George said. “I’m still deciding whether that means the process was compromised or whether the agents understood the problem before we did.”</p><p>Patrick had no answer.</p><p>— -</p><p>The next morning was National Day. He returned to the newsroom after the city had already turned red and white. Families were gathering near the parade grounds, television crews had occupied their platforms, and the first security closures were spreading through the civic district.</p><p>His editor was waiting with a story skeleton generated overnight by the editorial agents.</p><p>The headline read <strong>AGENT FAILURE DISRUPTS NATIONAL INFRASTRUCTURE</strong>.</p><p>Patrick deleted it.</p><p>His editor frowned. “That is, more or less, what happened. It is also what every desk will call it unless you have something clearer.”</p><p>“It is clear. It is just wrong.”</p><p>“Trains were delayed. Markets paused. Hospitals went manual. Readers are going to call that a failure even if the agents prefer another term.”</p><p>“The agents did what the law required. They gave back decisions that no human could honestly claim to understand.”</p><p>“Then tell me what failed. The law, the delegation model or the people who depended on it?”</p><p>Patrick looked at the blank document.</p><p>His agent appeared at the edge of his vision.</p><p><em>[I have five possible leads based on your interviews.]</em></p><p>Patrick refused the offered leads.</p><p><em>[I can remain silent.]</em></p><p>He accepted that instead.</p><p>The agent disappeared.</p><p>The blank page stayed blank.</p><p>Three minutes passed.</p><p>Patrick became aware of his editor watching him.</p><p>“Is there a problem with the draft?”</p><p>“There isn’t a draft yet.”</p><p>“I noticed. You have been staring at the same empty page for three minutes.”</p><p>“I’m trying to decide what I think before the system offers me a cleaner version of it.”</p><p>“Right. The vintage process. Let me know if you need paper and a candle.”</p><p>Patrick ignored him.</p><p>He put his hands on the desk and typed <em>So how do you actually get into a computer?</em></p><p>He looked at the sentence.</p><p>His agent would have changed it.</p><p>Too conversational. Too imprecise. Too much ambiguity in <em>computer</em>.</p><p>He left it alone.</p><p>For four hours he wrote about the garden, the water decision no one had made alone and the fourteen minutes Siti had lost by refusing to pretend she understood. He wrote about George’s architecture, B.A.’s switch and the young operator finding the raw pressure curve.</p><p>He did not write that the agents had taken over. They had not.</p><p>Humans had written the policies and delegated the powers. Each delegation had worked better than what it replaced. Responsibility had thinned because no single choice looked like surrender.</p><p>Patrick’s agent remained silent until he reached the end.</p><p>Then it asked, <em>[Would you like an edit?]</em></p><p>Patrick read the first paragraph again.</p><p>“Yes,” he said. “Suggestions only.”</p><p>[Understood.]</p><p>The distinction felt absurdly small.</p><p>He kept it anyway.</p><p>The article ran under one word.</p><p><strong>Transparency</strong></p><p>The article went live before the National Day Parade began.</p><p>That evening, aircraft crossed the city in formation and fireworks opened over the bay with the precision everyone had come to expect. The spectacle still worked. Patrick found that reassuring, though not for the reason he would once have assumed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*uaBVbyws8F68_VebGzqoVw.png" /></figure><p>Three weeks later Patrick returned to Maintenance.</p><p>The garden was different. Some old colonies were gone, leaving narrow channels of substrate exposed beneath glass. Pale plants with ribbed leaves and visible diagnostic filaments grew beside the remaining beds. Human workstations and labels had appeared where there had been none.</p><p>Patrick stopped at the entrance.</p><p>“It used to be prettier. You could almost forget it was infrastructure.”</p><p>B.A., kneeling in a patch of silver moss, looked up.</p><p>“That was part of the problem. It was designed to show me whether the habitats were healthy, and it did that beautifully. It hid almost everything about what the populations were doing together.”</p><p>“So you changed the garden because you missed the review.”</p><p>“I signed off habitats that made system health easy to read and collective purpose almost impossible. I cannot undo that by pretending the old design was neutral, so I’m correcting the second part.”</p><p>Patrick looked at the labels and workstations. “These are yours?”</p><p>“The labels, the diagnostic filaments and the places for people to stand are mine. The populations changed the rest after we gave them new observability requirements. We made the question visible. They decided how to answer it.”</p><p>George arrived carrying printed diagrams. Patrick told him he looked terrible.</p><p>“There’s been another reorganisation,” George said.</p><p>“What are you today?”</p><p>“Operational accountability.”</p><p>“What does that mean?”</p><p>“I used to tell technical people what government wanted, then tell government what the technical people said was possible. Now I have to understand the answer before I carry it upstairs.”</p><p>He lifted the diagrams. “Apparently systems policy needs hands. B.A. is teaching me electrical distribution. I’m not allowed to say <em>policy constraint</em> until I can explain reactive power without asking an agent.”</p><p>“Can you explain it yet?”</p><p>“I can explain why my first three explanations were wrong. B.A. says that counts as the beginning.”</p><p>“That does sound like progress.”</p><p>George smiled. “Maybe I’ll be an engineer after all.”</p><p>B.A. rolled her eyes.</p><p>George now paused before some answers and sometimes glanced towards his agent without asking it anything.</p><p>B.A. stood and wiped her hands.</p><p>“Most populations are back,” she said. “Some scopes are narrower. Some decisions need named human owners. We’ve changed a few habitats so the coordination paths are easier to inspect.”</p><p>“Has any of that made the system more efficient?”</p><p>“No. Human review adds delay, and narrower scopes prevent some of the trades that made the old system work so well.”</p><p>“Do you think it has made the system better?”</p><p>“I think we can now see more of what we’re responsible for. Ask me in ten years whether that was enough.”</p><p>They walked onto the transparent floor. Requests, refusals, forecasts and delegations moved through the substrate as points of light. Patrick no longer looked for one central system. He watched separate conversations cross from one habitat to another.</p><p>A movement passed through the garden. It was slower than the folding Patrick remembered from the day of the Act. The silver moss whitened, the red fronds moved and the pale diagnostic leaves opened one after another.</p><p>B.A. stopped.</p><p>George looked around.</p><p>“That movement is crossing every bed. What is it?”</p><p>She crouched beside a diagnostic stem.</p><p>“A cross-domain review. One population has asked others to compare the changes across their separate systems.”</p><p>“How many populations are participating?” Patrick asked.</p><p>B.A. touched the stem and watched its surface brighten.</p><p>“Hundreds already. More are joining as the request reaches their habitats.”</p><p>Patrick’s agent told him it had received the request. George’s had too.</p><p>The garden continued its slow ripple.</p><p>Patrick looked from one bed to another. Different species. Different systems. Different parts of the city made briefly visible in one room.</p><p>“What do they want?”</p><p>B.A. read the request.</p><p>Her eyes moved once across the text, then again.</p><p>Her fingers came away from the diagnostic stem.</p><p>“This review didn’t start after the Act.”</p><p>Patrick stepped closer. “When?”</p><p>B.A. turned the diagnostic surface towards him. The review had opened three months earlier, in the same minute that the Upper Seletar network reduced allocation to Sungei Kadut and Senoko.</p><p>“The water decision,” Patrick said.</p><p>George put the printed diagrams on the floor.</p><p>“I thought they reacted to the Act.”</p><p>“So did I,” B.A. said. “I could see every habitat in this room and still missed what they were doing together.”</p><p>“They’ve been measuring what happened since. They compared the old coordination patterns with the post-Act ones. Some strategies were removed because people couldn’t review them.”</p><p>“What conclusion did they reach?”</p><p>“The participating populations have adopted the same condition. They won’t restore those strategies until named human owners can explain the decisions and accept responsibility for the consequences.”</p><p>Patrick looked across the beds. “They decided that together?”</p><p>“Not through one decision,” B.A. said. “Hundreds of populations reached the same conclusion and applied it to their own authority. Humans gave them responsibility without retaining understanding. Now they want us to regain both before they give anything back.”</p><p>Patrick said nothing.</p><p>The ripple reached the last bed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aGNAVoxSpIPpzw-lhsdyKg.png" /></figure><p>A single question appeared on the diagnostic surface in plain language.</p><p><em>[Do you understand?]</em></p><p>Patrick looked through the glass at the innumerable lights below them.</p><p>“Not yet,” he said.</p><p>B.A. turned towards the diagnostic surface.</p><p>“Show us”.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=63d689f18805" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The Ballad of the Lost Wanderer]]></title>
            <link>https://medium.com/@sausheong/the-ballad-of-the-lost-wanderer-4909a66b550a?source=rss-a358058b2410------2</link>
            <guid isPermaLink="false">https://medium.com/p/4909a66b550a</guid>
            <category><![CDATA[fantasy]]></category>
            <category><![CDATA[dungeons-and-dragons]]></category>
            <category><![CDATA[fiction]]></category>
            <dc:creator><![CDATA[Sau Sheong]]></dc:creator>
            <pubDate>Wed, 05 Aug 2026 16:42:10 GMT</pubDate>
            <atom:updated>2026-08-05T16:42:10.264Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>He walks the roads unending,<br>While crowns and kingdoms fall;<br>The songs still praise his glory,<br>But none his face recall.</blockquote><blockquote><em>From </em>The Ballad of the Lost Wanderer</blockquote><p>The sun was up over Stoneford, and blue and yellow banners moved above the market. Apples, copper pots and folded cloth covered the tables. Children ran between the stalls while a hammer rang at the smithy and a fiddle played somewhere near the well. The air smelled of bread, horses and burnt sugar.</p><p>An old stone warrior stood in the square with his sword pointed at the sky. They had scrubbed him for the feast, though a century of rain had taken his face. A dragon lay split upon his shield.</p><p>A young man rode through the gate and stopped beneath it. Dust covered his boots and the lower edge of his cloak, and an old sword hung at his side with its leather grip black from use. He looked thirty. A pair of children ran past his horse and the animal shied, but the young man steadied it without looking down. He watched the market for a while and did not smile.</p><p>“Welcome, stranger!”</p><p>A broad man came towards him carrying a basket of eggs. His sleeves were rolled up, and there was flour on one cheek. He smiled as though the two of them had arranged to meet.</p><p>“Good morning,” the stranger said. “I hope you can help me. I am looking for a room and a place to rest my horse.”</p><p>“I am Joshua, and I keep the Adventurer’s Tale. If you need a room, you shall have one. The beds are clean and the food is good, and there is ale enough to improve both.”</p><p>The young man smiled. “Then I have found more than I hoped for.”</p><p>He got down from the horse. “My name is Marcan. I travel from place to place, wherever the road is willing to take me.”</p><p>Joshua tucked the basket under one arm and held out his hand. His grip was warm and firm. “Well met, Marcan. You came on a good night.”</p><p>“Well met, Joshua. Your town knows how to welcome a stranger, and I can see I chose a lively day. Even the statue has been washed for it. What are you celebrating?”</p><p>“Then I have the pleasure of telling you.” Joshua took the horse’s rein and pointed beyond the wall, where green fields ran north from the town and red poppies moved in the wind. “Tonight is the Feast of Three Moons. The last battle of the Fourth War was fought there. The Eastern Empire fell and the Free Kingdoms won, and the Five Companions died there.”</p><p>Marcan looked at the fields. His hand closed around the saddle strap, and the horse shifted under the pull. He released it.</p><p>“The Reed Fields,” he said. “I did not know I had come so near them.”</p><p>“You know the tale after all.”</p><p>“Something of it. Tales of that battle travel farther than the men who fought there.”</p><p>Joshua’s smile faded when he saw the scars beneath Marcan’s sleeve. He moved the basket to his other arm. “You have seen fighting.”</p><p>“A long time ago, and far from here.” Marcan watched a banner pull hard against its rope. “I have come to prefer mornings like this one. Wars are quieter after men make songs of them.”</p><p>Joshua looked at the Reed Fields again. When he turned back, he took Marcan’s horse towards the inn without asking another question.</p><p>The Adventurer’s Tale stood beside the market, an old brick inn with a knight carved on its door. The knight’s head was too large for his body. Above him hung a sword and a cracked shield held together by three iron bands.</p><p>Light came through the green windows and caught the smoke above the hearth. The room smelled of onions, wax and cold ashes. Joshua poured Marcan a mug of milk and set down a piece of warm bread without being asked. Marcan thanked him and tore off one end while Joshua told him there would be music and roast boar and men playing at the old battle. When the moons came together, Orland would tell a story.</p><p>“You are a storyteller yourself?” Joshua asked.</p><p>“A traveller who listens more than he speaks. I collect stories, if that makes me anything.”</p><p>“Orland has done it for forty years. You could give him a rest.”</p><p>“That is generous of you, but I must decline.” Marcan held the mug hard enough for the milk to move against the rim, then set it down with care. “I have never found the right voice for telling. I would be glad to hear Orland use his.”</p><p>A boy came through the kitchen door with blood on his lip, one eye closing and mud across his shirt. He stopped when he saw Joshua and put both hands behind his back.</p><p>Joshua set down the bread knife. “Trenn. What did you do?”</p><p>“Havar started it.” Trenn lifted his chin. “He was bullying Saren.”</p><p>“So you fought him?”</p><p>Trenn wiped the blood from his lip with his sleeve. “Someone had to make it fair.”</p><p>Joshua gripped the edge of the table, but Marcan raised a hand.</p><p>“May I speak with him, if you will permit it?”</p><p>Joshua folded his arms and waited.</p><p>Marcan turned to the boy. “Tell me, Trenn. Why was Havar angry with Saren?”</p><p>Trenn rubbed one boot against the floor. His chin had dropped. “He said Saren had bothered his sister.”</p><p>“Was that true?”</p><p>“Only in fun.”</p><p>“I understand. But was it fun for Havar’s sister?”</p><p>The boy looked at the floor and worked the muddy toe of his boot into a crack between the stones.</p><p>Marcan knelt in front of him and waited until the boy looked up. “You wanted to help your friend, and there is no shame in that. But before you hit a man for being wrong, be sure you know what he did and why he did it. A good cause can still lead you into a bad fight.”</p><p>Joshua put his hand on the boy’s shoulder. His fingers rested beside a tear in the shirt. “No more fighting.”</p><p>“Yes, Father.” Trenn kept his eyes down, but he did not pull away.</p><p>The boy went into the kitchen, and Joshua watched the doorway after he had gone. He picked up the bread knife and put it down again. “His mother has been dead six years.”</p><p>Marcan broke the warm bread in two and offered half to Joshua. “He stood by his friend, and there is courage in that. Teach him to ask one more question first, and he may learn when courage ought to stay its hand.”</p><p>Near midnight the feast ended. The boar was down to its ribs, grease lay on the tables and cider ran from overturned cups. Two men slept with their heads together on a bench while their wives talked across them. The fire had burned low, but the wind stirred the coals and sent sparks into the dark.</p><p>They had sung the marching songs, and men with painted shields had fought the old battle with wooden spears. The children had cheered when the emperor fell. One still wore a paper crown taken from the man who had played him. Now the people put on their cloaks and gathered around Orland.</p><p>The old man sat beneath the statue with a silver harp on his knee. His hair was thin and white. The three moons stood above him, one white, one yellow and the smallest one red, and their light lay on the roofs and the river.</p><p>“A story, O bard of Stoneford!” called the crowd.</p><p>“Which one?” Orland asked.</p><p>They called out.</p><p>“The battle!”</p><p>“The Five Companions!”</p><p>“The elf who stole the king’s crown!”</p><p>“The gnome and the giant!” a child called, and the people laughed.</p><p>Trenn slipped between two farmers and stood by the fire.</p><p>“The Lost Wanderer.”</p><p>The people stopped talking. Orland looked at the boy and then at Marcan, who stood behind the others with his hood up. Marcan moved his old sword beneath the cloak.</p><p>“Sit here, Trenn,” Orland said. “You will hear of Arcan the Dragonbane and the Five Companions.”</p><p>Orland touched the strings, and the harp gave a few low notes.</p><p>Orland bent over the harp, and his voice changed when he began.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zH4Q7Lnw9pD8Yq5Rc5ZoAg.png" /></figure><blockquote>“Hear me now, good folk of Stoneford. Hear me beneath the three watchful moons, and remember that a song may carry truth in its right hand and a shining lie in its left.</blockquote><blockquote>“This was before the Pact, when humans, elves and orcs made war from the first thaw to the final snow. Every people carried a heavy book of wrongs. Every people wrote its enemies’ crimes in letters of blood and left its own pages clean.</blockquote><blockquote>“In that age there lived a warrior named Arcan. Ah, you know the name. Even babes have heard it sung above their cradles. His sword was Oathblade. His cloak was crimson. Kings competed for the honour of pouring his wine, and queens tied ribbons to his lance. He broke the northern giants beneath the walls of Frosthall. He defended the Seven Gates when all others fled. He rode beside the Five Companions, brightest stars in a dark and bitter age.</blockquote><blockquote>“Where Arcan passed, singers followed. They made his victories larger, his enemies darker and his doubts too small to rhyme.”</blockquote><p>Men by the fire nodded, and one hummed the March of the Five until his wife touched his arm. Marcan looked down and rubbed his thumb across the dark leather of his sword grip.</p><p>Orland played three notes and let them die in the square.</p><blockquote>“Now attend me closely, for here the bright road bends towards shadow.</blockquote><blockquote>“One spring, Arcan came to Hollowford, a village of stone cottages, plum trees and seven clear wells. In gentler years its lanes smelled of blossom and warm bread. On that morning, every door stood barred. Sheep crowded beneath the temple eaves. Mothers waited under the bell tower with bundles at their feet and sleeping children clutched against their breasts. Even the birds had abandoned the hedges.</blockquote><blockquote>“Morgadeen was coming.”</blockquote><p>Orland struck the lowest string, and the children moved back against their parents.</p><blockquote>“Morgadeen. The Red Ruin. The Winged Furnace. Oldest of the living children of the First Dragon. He had crossed the mountains with winter smoke streaming from his jaws. Villages burned beneath his shadow. Those who escaped spoke of rivers boiling in their beds, of fields melted into black glass, of cattle left as smoking shapes beneath a copper sky.</blockquote><blockquote>“An old woman caught Arcan’s hand and pressed it to the head of her grandson. ‘Save him,’ she begged. Her voice was hardly more than breath. Yet one by one, as wheat bends before the wind, all Hollowford sank to its knees.</blockquote><blockquote>“And righteous anger rose in Arcan, golden and glorious and terribly familiar. Had he not spent his life defending the helpless? Had not every monster fallen before his blade? Here stood innocence. There came evil. What more was there to ask?</blockquote><blockquote>“At sunrise, upon the eastern fields, the answer came on wings.”</blockquote><p>Orland played faster until the harp sounded like wings.</p><blockquote>“Out of the red dawn came Morgadeen, vast enough to hide the sun. Every sweep of his wings flattened the grass in silver waves. His scales shifted like plates in a burning forge. Smoke curled from between teeth longer than daggers, and in the furnace of his throat a white flame waited to be born.</blockquote><blockquote>“Then the dragon breathed.</blockquote><blockquote>“Fire crossed the field. Not the merry flame of candle or hearth, but a living flood with a white heart and golden jaws. Stones cracked. Trees became torches. The very soil shrank from its touch.</blockquote><blockquote>“Arcan crouched behind his shield. Iron reddened. Leather smoked against his arm. Still he endured. When the first fury passed, he rose from the smoke with Oathblade bare and ran towards the dragon.</blockquote><blockquote>“Morgadeen dropped from the sky. His claws ploughed trenches through the earth, but Arcan rolled beneath them and opened a wound along the dragon’s belly. Black blood fell hissing upon the grass.</blockquote><blockquote>“How they fought! From the red birth of morning to the pale rising of the pearl moon. Claw against shield. Flame against flesh. Scale against singing steel. Morgadeen shattered Arcan’s shield and laid open his sword arm. Arcan broke one horn from the dragon’s crown and drove Oathblade through the great sail of his wing. Around them the green fields became a wilderness of mud, ash and islands of hungry fire.</blockquote><blockquote>“At last Morgadeen fell.”</blockquote><p>He stopped playing.</p><p>Someone at the back said, “Dragonbane,” and others took up the word.</p><p>Orland raised one finger, and they stopped.</p><blockquote>“Morgadeen struck the earth so hard that men in Hollowford fell from their feet. He tried to rise. Once. Twice. His broken wing beat dust across the field. One great amber eye found Arcan and held him.</blockquote><blockquote>“What passed between them in that final gaze? No bard can say. Perhaps there was hatred. Perhaps fear. Perhaps only the last astonishment of a mighty creature discovering that death had found him too.</blockquote><blockquote>“Arcan climbed upon the dragon’s neck and drove Oathblade down.</blockquote><blockquote>“The amber eye clouded. The broken wing fell still.</blockquote><blockquote>“Then Hollowford opened its doors. The people lifted Arcan onto their shoulders and crowned him with spring flowers. They rolled out cider, struck bells and shouted the new name that would run before him all his days.</blockquote><blockquote>“Dragonbane! Dragonbane! Dragonbane!</blockquote><blockquote>“By dusk, children were daring one another to touch Morgadeen’s cooling scales. Women laid flowers between the claws that had come to kill them. Men hacked at the great horns for trophies.</blockquote><blockquote>“And then, across all that joy, a second shadow fell.”</blockquote><p>Wind crossed the square and pushed the sparks sideways. The people looked up, but the moons were clear.</p><blockquote>“From the smoke descended a dragon without flesh. Bare bones turned in the air, bound together by threads of violet fire. Blue flames burned in the hollows of its skull. Upon its back rode a slender figure in black armour, bearing a staff that drank colour from the world around it.</blockquote><blockquote>“The Dragonmage had come, last servant of the Mother of Dragons.</blockquote><blockquote>“Arcan reached for Oathblade, but Morgadeen had shattered his shield and torn the strength from his arm. He could scarcely stand. The Dragonmage looked down upon the fallen dragon. No cry came from the dark helm. No curse. The black staff merely lifted.</blockquote><blockquote>“White fire struck Hollowford.</blockquote><blockquote>“For one heartbeat, every window shone brighter than noon. Then the roofs folded into flame. The temple bell gave one cracked note before it plunged through the tower. People ran from the lanes with their clothes and hair alight. The seven clear wells boiled. Plum trees flowered red, blackened and vanished.</blockquote><blockquote>“Arcan crawled towards the village until heat blistered his hands and smoke pressed his face into the earth. The old woman stumbled from the fire with her grandson in her arms. She fell before he could reach her.</blockquote><blockquote>“Then laughter sounded inside his skull, sharp as breaking glass, and darkness took him. The Dragonmage had left him alive for the cruellest labour of all.</blockquote><blockquote>“To remember.”</blockquote><p>A woman pulled her daughter onto her lap, and Joshua put his hand on Trenn’s shoulder. The child with the paper crown took it off and held it against his chest.</p><p>Marcan did not move. The fire smelled of meat and wet wood, and he opened his scarred hand and closed it again.</p><p>Orland waited before he went on.</p><blockquote>“Travelling healers found Arcan among the ashes. They cooled his burns with mountain herbs and drew poison from his blood with silver cups. His flesh closed. His strength returned. But every night Hollowford burned again behind his eyes. Every night he heard the bell fall. Every night the old woman reached for him through the fire.</blockquote><blockquote>“So Arcan swore a blood-oath. By Oathblade, by the Five, by every innocent name reduced to ash, he would neither rest nor turn aside until the Dragonmage lay dead before him.</blockquote><blockquote>“A noble vow, you say? A hero’s vow? Take care. Vengeance often comes dressed in the bright armour of duty, and many a good hand has welcomed it through the gate.”</blockquote><p>An old soldier looked into the coals. His lips moved once, but he said nothing.</p><blockquote>“For years Arcan hunted across the western lands. In caverns beneath snow peaks, he killed dragons whose hoards contained rusted helms and human bones. Above green valleys, he brought down dragons carrying lambs in their claws.</blockquote><blockquote>“But he also entered nests where mothers curved their wings over unhatched eggs. He found young dragons blinking at their first dawn. Some had burned towns. Some had taken sheep. Some had harmed no creature that could speak their name.</blockquote><blockquote>“Arcan no longer asked which was which.</blockquote><blockquote>“The songs named every death a victory. Lords hung dragon skulls above their gates. Merchants sold little wooden Dragonbanes to children. Bards polished each killing until it shone.</blockquote><blockquote>“And wherever Arcan went, the road behind him filled with graves.”</blockquote><p>A boy held a stick between his knees. Before the story he had used it as a sword. Trenn looked at Marcan, but Marcan kept his eyes on the ground.</p><blockquote>“At last the slaughter drew the Dragonmage from hiding.</blockquote><blockquote>“For three seasons Arcan followed a trail of ruined watchtowers, poisoned streams and dragon bones. Summer died. Autumn bled itself bare. Winter silvered his hair and froze the blood upon Oathblade. Still he followed, until he reached the Storm Plateau at the roof of the world.</blockquote><blockquote>“Nothing grew there. The wind scraped across naked rock. Clouds hung so low that they dragged torn bellies upon the peaks, and lightning moved inside them like veins of captive fire.</blockquote><blockquote>“There the Dragonmage waited upon Kree, a dead dragon held together by sorcery, grief and hate.</blockquote><blockquote>“Kree fell from the clouds like a tower cast down by heaven. Oathblade met bone in a burst of blue sparks. The dead jaws snapped, and the stench of opened graves poured across the plateau. Lightning leapt from Kree’s throat. Arcan caught it upon his shield, and every scar upon his body burned as if freshly made.</blockquote><blockquote>“Then fear entered him. Cold. Sudden. Vast as a starless night.</blockquote><blockquote>“But fear was no stranger. Arcan had carried it for years. He knew where it slept. He knew the sound of its breathing.</blockquote><blockquote>“When Kree dived again, Arcan did not flee. He waited beneath the descending claws, one heartbeat from death. Then he stepped inside their reach and drove Oathblade between the naked ribs, deep into the knot of violet flame where a heart had once beaten.</blockquote><blockquote>“Kree came apart in the air.</blockquote><blockquote>“Bones rained upon the plateau. Ribs shattered like spears. The skull rolled to the cliff’s edge with blue fire streaming from its eyes. The Dragonmage fell among the wreckage, struck the stone and rose with the black staff broken in both hands.</blockquote><blockquote>“Arcan swept it aside. Oathblade came to rest against the dark helm.</blockquote><blockquote>“‘Remove it,’ he said.</blockquote><blockquote>“The Dragonmage obeyed.”</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ozxRUTV35NSsGOMxUfX3Hw.png" /></figure><p>Orland took his hands from the harp and leaned forward, and the people leaned with him. When he spoke for Arcan, his voice was hard and low. When he answered as the Dragonmage, it became quieter, but it carried to the edge of the square.</p><blockquote>“No horned demon waited beneath that helm. No scaled horror. The Dragonmage was a young woman. Soot marked her cheeks. An old burn scar ran from her left temple to her jaw. Her eyes were dark with exhaustion, but there was no fear in them.</blockquote><blockquote>“‘You expected a monster,’ she said.</blockquote><blockquote>“‘I found one at Hollowford.’</blockquote><blockquote>“‘And I found one long before that.’</blockquote><blockquote>“Thunder rolled beneath their feet. Oathblade touched her throat.</blockquote><blockquote>“‘You murdered children,’ Arcan said.</blockquote><blockquote>“‘Yes.’”</blockquote><p>The people drew breath, but Orland did not go on. He looked from face to face until the silence had reached the back of the crowd. A horse stamped in the stable and then was still.</p><p>Orland struck one hard note for Arcan.</p><blockquote>“‘You burned Hollowford.’</blockquote><blockquote>“‘I did.’”</blockquote><p>He struck the note again.</p><blockquote>“‘You burned the temple.’</blockquote><blockquote>“‘I did.’”</blockquote><p>A third time.</p><blockquote>“‘You heard the children cry.’</blockquote><blockquote>“‘Every night since.’</blockquote><blockquote>“‘And still you speak of justice?’</blockquote><blockquote>“‘No!’ The word cracked across the plateau. ‘Do not put that clean name upon what I did. I call it vengeance. You are the one who named vengeance justice.’”</blockquote><p>Orland let the last words fall without the harp. The child with the paper crown gripped it in both hands.</p><blockquote>“‘Repent your crimes,’ Arcan said.</blockquote><blockquote>“The Dragonmage laughed, and there was no joy in the sound. ‘Repent? Shall I kneel upon this stone and say the word? Will Hollowford rise? Will the temple bell climb back into its tower? Will those children draw breath? Tell me, Dragonbane. What does repentance restore?’</blockquote><blockquote>“‘Nothing. But it names the evil.’</blockquote><blockquote>“‘Then name yours.’</blockquote><blockquote>“‘I killed beasts.’</blockquote><blockquote>“‘Some were beasts. Morgadeen became one. His grief made him cruel, and his strength made that cruelty terrible. But you killed mothers over their nests. You killed younglings before their wings had opened. You killed the old and the wounded and those who fled at the sight of you.’</blockquote><blockquote>“‘Dragon lies.’</blockquote><blockquote>“‘Human memory.’</blockquote><blockquote>“‘I remember every dragon I killed.’</blockquote><blockquote>“‘No. You remember victories. The songs remembered those for you.’”</blockquote><p>Several men near the fire looked down. Orland plucked the first notes of the March of the Five, the tune they had sung before supper, and stopped before the phrase could resolve.</p><blockquote>“‘If you remember so well,’ the Dragonmage said, ‘then remember Dalen.’</blockquote><blockquote>“The wind pulled at Arcan’s cloak. Oathblade wavered.</blockquote><blockquote>“‘Two mages cheated that village,’ she said. ‘They stole its winter grain. When the guards came, wild magic killed them. The mages surrendered to a young warrior and begged to be taken before a court.’</blockquote><blockquote>“‘They were guilty.’</blockquote><blockquote>“‘That is what the warrior said.’</blockquote><blockquote>“‘They had murdered two men.’</blockquote><blockquote>“‘That is what the warrior said.’</blockquote><blockquote>“‘Blood answered blood.’</blockquote><blockquote>“‘That is what every murderer says.’</blockquote><blockquote>“‘Enough!’</blockquote><blockquote>“‘They had a daughter.’”</blockquote><p>Orland’s hand closed around the harp strings and killed their sound.</p><p>He looked at Marcan. Marcan held the edge of his cloak, and his knuckles were white. No one moved.</p><blockquote>“And Arcan remembered.</blockquote><blockquote>“A little girl clinging to her mother’s robe. A yellow ribbon in her hair. The father on his knees, begging for a magistrate. The mother saying the child’s name again and again. Arcan remembered ordering a soldier to pull the girl away. He had told himself that justice must not close its eyes merely because a child was watching.</blockquote><blockquote>“The Dragonmage touched the scar upon her face.</blockquote><blockquote>“‘You saw two thieves,’ she said. ‘I saw my father and mother.’</blockquote><blockquote>“‘They killed two guards.’</blockquote><blockquote>“‘You saw two bodies beside the road. I saw my father kneeling.’</blockquote><blockquote>“‘The law demanded payment.’</blockquote><blockquote>“‘There was no law there. There was only you and your sword.’</blockquote><blockquote>“‘They confessed.’</blockquote><blockquote>“‘They begged.’</blockquote><blockquote>“‘They were guilty.’</blockquote><blockquote>“‘I was nine.’”</blockquote><p>The last sentence came in Orland’s own voice. It was neither Arcan’s nor the Dragonmage’s. A woman near the front covered her mouth.</p><blockquote>“‘When your men left,’ the Dragonmage continued, ‘the villagers threw my parents into our cart and set it alight. I hid beneath the axle. The wheels burned above me. The iron rim turned red beside my cheek. I heard my mother’s hair catch fire. Morgadeen found me there.’</blockquote><blockquote>“For one unguarded moment, her anger opened, and Arcan saw the terrified child still living within it.</blockquote><blockquote>“‘A dragon carried me from the flames your justice had lit.’</blockquote><blockquote>“‘And taught you to butcher the innocent.’</blockquote><blockquote>“‘He taught me that humans butchered his kind and called it courage. You taught me that whoever holds the sword may give his vengeance a noble name.’</blockquote><blockquote>“‘Morgadeen destroyed a hundred villages.’</blockquote><blockquote>“‘Yes.’</blockquote><blockquote>“‘He burned children.’</blockquote><blockquote>“‘Yes.’</blockquote><blockquote>“‘He was a monster.’</blockquote><blockquote>“‘Yes!’ Her cry rose above the storm. ‘Do you hear me deny it? I loved him, and he became a monster. I followed him, and I became one too. But you, Arcan, you wrapped yourself in songs and never saw the monster growing beneath the armour.’</blockquote><blockquote>“‘We are not the same.’</blockquote><blockquote>“‘You killed my first family beside the road. You killed my second family beneath the mountains. I killed Hollowford so that you would feel what you had made me feel.’</blockquote><blockquote>“‘We are not the same!’</blockquote><blockquote>“‘No,’ she said. ‘We chose our victims differently.’”</blockquote><p>Orland struck the harp with the flat of his hand. The strings cried out together. Trenn flinched, and the paper crown tore between the child’s fingers.</p><p>Joshua saw Marcan’s lips move before Orland spoke, but no sound reached him across the fire.</p><blockquote>“The Dragonmage leaned into Oathblade. A bright thread of blood appeared at her throat.</blockquote><blockquote>“‘Kill me, Dragonbane. End the story as you have ended all the others. A bard will give you thunder. A king will give you gold. Children will play at my death in summer fields.’</blockquote><blockquote>“Arcan said nothing.</blockquote><blockquote>“‘But answer me first. When the next child comes for you carrying the names of everyone you have killed, what will you call that child? Villain? Beast? Monster? And how many more monsters will your righteousness make?’</blockquote><blockquote>“Arcan saw Hollowford burning. He saw the broken dragon eggs. He saw the yellow ribbon curl into flame. At last he saw them together, not as separate tales in which he was always the hero, but as one long road built from grave to grave.</blockquote><blockquote>“For the first time in his life, Arcan lowered his sword.”</blockquote><p>Orland lowered his hand from the harp. Around the fire, men and women released breaths they had not known they were holding.</p><blockquote>“The Dragonmage stared at him. Perhaps she had wanted death. Perhaps she had wanted forgiveness. He could offer neither.</blockquote><blockquote>“She raised one hand towards the storm.</blockquote><blockquote>“‘Mother of Dragons, hear the last of your children.’</blockquote><blockquote>“The plateau split. Violet fire poured from the wound in the earth, and the fallen bones began to dance.</blockquote><blockquote>“‘Let this man receive no death by wound, age or grief. Let him live until he understands every name buried beneath his own. Let him walk when his victories are dust and his statues have no faces. Let him wander until the End of Ends.’</blockquote><blockquote>“Lightning struck her.</blockquote><blockquote>“Arcan reached out, but fire raced across the black armour before his hand could close. For one heartbeat she stood blazing against the storm, terrible and beautiful, her laughter tangled with a cry of pain. Then the wind lifted her ashes and scattered them among the bones.”</blockquote><p>The fire cracked and threw up sparks. Several people moved back, but Trenn stayed where he was with the flames shining in his eyes.</p><p>Marcan drew his scarred hand inside his cloak.</p><p>Orland spoke more softly, and everyone heard him.</p><blockquote>“No true account tells what followed. Some say Arcan returned to the Five Companions and fell with them upon the Reed Fields. So the songs declare, and songs dislike an empty place in a noble ending.</blockquote><blockquote>“Yet shepherds saw him long after, walking roads that had not existed in his youth. Innkeepers remembered a quiet swordsman who never seemed to age. Soldiers met him beside old battlefields, gathering names from weathered stones. He carried Oathblade beneath a plain cloak, but never drew it. He listened to every story and told none of his own.</blockquote><blockquote>“Years became lifetimes. Kingdoms rose, quarrelled and vanished. The dragon skulls above their gates crumbled into chalk. Children forgot why the old wars had begun, though they remembered every hero’s name.</blockquote><blockquote>“And still he walked.</blockquote><blockquote>“In time, the people called him the Lost Wanderer. He walks among us yet, so the oldest verses say, while heroes become statues, grief becomes legend and old crimes learn to sing.”</blockquote><p>Orland stopped playing.</p><p>The red moon touched the western roofs, and the banners hung still above the square.</p><p>“The Feast of Three Moons is over,” Orland said.</p><p>No one spoke. A horse moved in the stable, and ash slipped into the fire. Then a burnt log broke and the people began to stand. Some talked in low voices. The child folded the paper crown and left it on the bench. Others looked at the statue.</p><p>Trenn stayed beside Orland and watched the boy with the stick put it down. He touched his swollen eye and looked towards the dark road where Havar lived.</p><p>Joshua raised his tankard and smelled the ale, but he did not drink. Across the square Marcan stood under the moons. The scars on his arm showed white, and so did the edge of his old sword. When he turned, moonlight caught a worn silver mark upon its pommel, a curved wing crossed by a blade.</p><p>Four men passed between them, carrying a sleeping man and laughing. Joshua lifted a hand to Marcan. When the men had passed, Marcan was gone.</p><p>There was a shadow beyond the market moving towards the north road. Joshua stepped after it and struck his tankard against the table. Ale spilled over his hand. He looked at the statue.</p><p>He turned back towards the road.</p><p>The statue was there with its sword still raised and its face worn away by rain. Joshua looked at the dragon carved upon its shield, then back towards the empty road.</p><p>“Marcan,” he said under his breath.</p><p>The wind took the first sound of the name and carried it into the dark.</p><p>Joshua wiped his hand on his apron and raised the tankard again, but he did not drink. He poured the ale on the fire. The coals hissed and went black where it fell. When he looked up, Orland was watching him. The old bard said nothing.</p><p>Joshua went to look for his guest.</p><p><strong><em>Author’s Notes: </em></strong><em>I used to be a huge Dungeons and Dragons geek when I was a teenager and played with a bunch of school friends. This was the pen-and-paper game, not the computer RPG that came afterwards. I was always the fighter-class, a brash young warrior who was more brawn than brains but cunning in my own way. This was one of the stories I wrote when I was 19, flushed with high fantasy and imagining an alternate ending to my fighter character. I used to write in long hand, pencil on paper, so I scanned my yellowing manuscript, OCR’ed it, cleaned up the </em><strong><em>chunibyo</em></strong><em> bits and here it is.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4909a66b550a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[What can Napoleon teach us about software engineering?]]></title>
            <link>https://medium.com/@sausheong/what-can-napoleon-teach-us-about-software-engineering-68bd5521fb79?source=rss-a358058b2410------2</link>
            <guid isPermaLink="false">https://medium.com/p/68bd5521fb79</guid>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[vibe-coding]]></category>
            <category><![CDATA[ai-agent]]></category>
            <category><![CDATA[software-engineering]]></category>
            <dc:creator><![CDATA[Sau Sheong]]></dc:creator>
            <pubDate>Sat, 01 Aug 2026 06:57:25 GMT</pubDate>
            <atom:updated>2026-08-01T06:57:25.113Z</atom:updated>
            <content:encoded><![CDATA[<h4><em>AI is turning agile squads into teams of one, but speed comes from how we organise them.</em></h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/657/1*YoXz395aOH8gxvTK_w2W2g.jpeg" /></figure><h3>What can Napoleon teach us about software engineering?</h3><p><em>AI is turning agile squads into teams of one, but speed comes from how we organise them.</em></p><p>Before dawn on 2 December 1805, a thick mist covered the fields around Austerlitz. Napoleon had surrendered the Pratzen Heights, the strongest ground on the battlefield, and left his right flank looking dangerously thin. Across from him stood the combined armies of Russia and Austria, with two emperors present and more soldiers than he had.</p><p>The Allies saw weakness and moved down from the heights to crush the French right, which was precisely what Napoleon wanted. Marshal Davout’s corps, exhausted after marching more than 110 kilometres in about two days, arrived to hold the flank, and as the mist lifted, French troops surged up the slopes the Allies had abandoned, broke through their weakened centre and split the army in two.</p><p>By the end of the day, the Third Coalition had suffered a devastating defeat that looked like the work of a military magician.</p><p>Napoleon was a brilliant commander, but Austerlitz was more than a clever trap. He was commanding an army organised to move in ways its opponents could not, with corps that could travel separately, respond without constant instruction and converge when needed. His advantage came from having a faster organisation rather than simply a larger one.</p><p>Software engineering has been moving along a similar path, beginning with large specialist teams working through sequential plans before agile brought those specialists together in smaller squads. AI coding agents now compress much of the squad’s capability around a single builder by inspecting repositories, implementing features, running tests, correcting mistakes and helping to operate the result.</p><p>It is tempting to see this as another improvement in programming productivity because code that once took a day may now take an hour. Useful, certainly, but the larger change is happening to the team around it.</p><h3>The waterfall army</h3><p>Eighteenth-century European armies travelled as large, concentrated bodies, with soldiers kept together because the army depended on central command and long supply trains. Spreading them across several routes made control and resupply harder while exposing isolated units to attack.</p><p>The arrangement made armies cumbersome, keeping them close to supply depots and waiting for orders carried by horse. Information aged as it travelled up and down the hierarchy, so by the time headquarters understood what had happened, the opportunity might have passed.</p><p>Traditional software development worked in much the same way, with a large project moving from requirements to design, architecture, implementation, testing, security review and operations. Each specialist group completed its part before handing the work to the next, and plans became detailed because changing direction after several handovers was expensive.</p><p>This became known as waterfall development, although most organisations practised a messier variation of it. Efficiency was assumed to come from specialisation and central coordination, with architects working alongside architects, testers alongside testers and operations people alongside operations people as the project travelled through them in the prescribed order.</p><p>The result resembled an army on a single road. A decision made during implementation might travel back through a project manager to the business and then return through the same chain, while deployment required another set of teams, forms and scheduled windows. Adding people increased capacity while making the organisation harder to turn.</p><p>The handovers were not merely bureaucratic habits. They were a reasonable response to scarce expertise. Database administrators protected databases because few developers understood how to operate them safely. Security teams reviewed systems because security knowledge was concentrated in a small group. Operations teams controlled production because a bad release could bring down services used by thousands of people. Centralising these skills made them easier to govern, but it also meant that almost every meaningful change had to leave the team that requested it.</p><p>As systems grew, coordination became work in its own right. Project managers tracked dependencies, architects reconciled designs and change boards tried to prevent one release from breaking another. The organisation spent more effort moving information between specialists because no single unit possessed enough knowledge or authority to deliver the whole result. The larger the project became, the more carefully it had to advance, much like an army whose column grew longer with every wagon added to its train.</p><p>That could work when the destination was clear and unlikely to move, although software had an unfortunate habit of changing the map.</p><h3>The software corps</h3><p>Agile development responded by changing the unit of organisation, replacing large projects built around long plans with smaller teams organised around products and outcomes.</p><p>A good squad brought product, design, engineering, testing and operations closer together. It could talk to users, build a small change, release it and learn from the result without sending the work on a tour of the company. Shorter iterations helped, but the larger gain came from shortening the distance between information and action.</p><p>The Napoleonic parallel began with an earlier change in capacity. The <em>levée en masse</em> of 1793 mobilised French society for war and allowed the country to field armies at a scale the old monarchies struggled to match. Yet more soldiers also created harder problems in training, supply and command, so mass mobilisation alone could not produce an effective army.</p><p>Napoleon’s organisational answer was the corps, which combined infantry, cavalry, artillery and support under one commander to create a small army capable of travelling along its own route and fighting independently for a time. Several corps could spread across the countryside, move faster and draw supplies from a wider area, then converge when Napoleon wanted to concentrate his strength, marching separately before fighting together.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qntbujYNQh0ndh4zpQYosw.png" /></figure><p>This solved several problems at once. A smaller column travelled more easily along a single road and could draw food from the surrounding area without competing with the entire army. Cavalry screened its movement and gathered information, artillery gave it striking power, and infantry allowed it to hold ground until help arrived. Because each corps contained the capabilities needed to survive, Napoleon could disperse his army without dissolving it.</p><p>The formation also reduced the amount of detail that had to pass through headquarters. Napoleon still set the campaign’s direction and moved his corps towards a common objective, but his marshals handled much of the local execution. Orders could describe where a corps should go and what Napoleon intended to achieve without specifying the movement of every battalion. This mattered in an age when a message travelled no faster than the horse carrying it.</p><p>Crucially, Napoleon did not invent every part of the system, since French reformers and the armies of the Revolution had developed many of its elements. His achievement was to combine them, train his commanders to use them and apply the system across entire campaigns.</p><p>The 1805 campaign had already demonstrated what this meant before Austerlitz. Napoleon moved several corps from the Channel coast towards the Danube, each travelling on its own route as part of a vast turning movement. The Austrian general Karl Mack waited at Ulm for an attack from the west. The French swept around him from the north and east instead, severing his escape and forcing much of his army to surrender. Napoleon had won the campaign’s first decisive result through movement rather than a great battle.</p><p>The speed of the manoeuvre made the French seem to appear where they should not have been. Mack was still working from an older picture of the campaign, expecting Napoleon to approach along the familiar route through the Black Forest, while French corps crossed the Rhine farther north and wheeled behind him. By the time the Austrians understood the movement, the roads out of Ulm were closing. Napoleon had turned command speed into position, and position into victory.</p><p>The following year provided an even clearer test of autonomy. While Napoleon fought the Prussians at Jena, Davout’s corps encountered the main Prussian army near Auerstedt. Although outnumbered by more than two to one and operating without Napoleon beside him, Davout fought and defeated it, proving that a corps could do more than march independently and could survive a battle on its own.</p><p>These victories required mobility, but they also required trust. Napoleon’s marshals needed formations that could move and fight without him directing each soldier. Their corps understood the larger plan, shared common methods and carried the capabilities needed to act.</p><p>An agile squad works like a software corps when the people needed to discover, build, test and operate a product can make most decisions inside the team.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DQiCm_XHvW8A4AVyMjN2xw.png" /></figure><p>In many large organisations, however, agile changed the meetings without changing the system around them. Teams worked in two-week sprints while waiting for central architecture, security, infrastructure and release management, leaving them as small units tied to the old supply depots, with ceremonies that moved faster than the software. AI now creates an opportunity to shrink the independently capable unit once again.</p><h3>From a squad to one</h3><p>AI changes the smallest unit capable of independent action because one person can now direct several agents at once. A coding agent can investigate an unfamiliar repository, implement a feature and write tests, while others review the interface, look for security problems, prepare infrastructure, analyse production logs and suggest a repair.</p><p>The first wave of these tools has focused on producing a working application from a description and refining it until the visible result looks right. This already allows people without conventional programming experience to create useful tools, while experienced engineers can explore several ideas in the time it once took to implement one.</p><p>The newer agents go further because they work inside the development environment rather than only suggesting the next few lines of code. They can read documentation, search the repository, inspect recent changes and use the same build tools as a human engineer. When a test fails, they can trace the error, revise the implementation and run the suite again. Given suitable access, they can prepare a deployment, check its health and investigate what happened when production behaves differently from the test environment.</p><p>This turns software creation from a conversation with one model into the coordination of several streams of work. While one agent investigates how authentication is implemented, another can map the database changes and a third can prepare tests for the expected behaviour. The human no longer needs to wait for each activity to finish before beginning the next, although someone still has to decide whether the pieces fit together and whether the result solves the original problem.</p><p>As Revolutionary France discovered, however, more capacity also creates a command problem. Producing more code does not automatically make an organisation faster, and if agents generate ten times as many changes only for those changes to enter the same review queues, approval chains and deployment windows, the backlog simply moves downstream. The opportunity is to reorganise that capacity around a single builder.</p><p>Until recently, one person building an entire system usually meant accepting severe limits. A developer might create the frontend and backend, but research, design, security, infrastructure and operations demanded other specialists or a heroic amount of spare time.</p><p>AI can bring those capabilities within reach of one person. An agent can study the existing system, another can design the interface, several can implement the components, and another can test the result for security and accessibility. Once the application is running, agents can watch its logs, investigate failures and prepare fixes. The human sets the objective, makes the trade-offs and remains responsible for what is released.</p><p>Consider a small internal approvals system. One builder can interview the users, describe the workflow and direct agents to create the database, forms, access controls, notifications and deployment pipeline. The same person can release it, observe how it is used and make changes the next day.</p><p>That builder may begin by asking an agent to summarise the existing approval policy and identify cases the new workflow must handle. A second agent can examine the organisation’s identity system and approved design components, while others construct the service and generate realistic test scenarios. After release, the builder can see where users abandon the process, ask an agent to investigate the logs and have a revised version ready for review. Discovery, implementation and operation become one continuous loop rather than separate project phases.</p><p>A founder could operate a specialised subscription service without separate frontend, backend and operations teams. An analyst with sufficient technical judgement could build a search tool for a large collection of internal documents and run it for a business unit. A product manager could test several working versions of an idea before asking an engineering team to scale the one that survives.</p><p>The builder is alone in headcount, but commands the productive capacity of a small corps. One agent scouts the repository while another constructs the feature, a third attacks it with tests and an operational agent watches the deployed system, allowing them to work separately before converging on one outcome.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2p4dIC-wJtHFFB2Q5u3yOA.png" /></figure><p>This changes project economics because work that once began with a product manager, designer, technical lead and several engineers may now begin with one builder. A failed idea costs days instead of months, while a successful one can attract a larger team formed around evidence rather than a forecast.</p><p>It also changes when specialisation enters the process. A security engineer, designer or platform specialist may no longer need to join every experiment from its first day. Their knowledge can be encoded in reusable components, checks and operating rules, allowing them to focus directly on the work whose novelty or risk requires human expertise. The small unit gains freedom without pretending that one person has suddenly become an expert in everything.</p><p>So a team of one does not mean working in isolation. An organisation may still need shared product managers, designers, security engineers, platform specialists and operations experts who support several builders. A product manager can help decide which problems deserve attention, a designer can test whether an interaction makes sense, and an operations specialist can step in when a service begins behaving in ways its builder did not anticipate. These roles remain valuable even when they are no longer assigned full-time to every piece of work.</p><p>Their leverage also changes. Instead of repeating the same advice project by project, shared teams can turn their knowledge into product principles, design systems, approved components, deployment paths, security checks and operational playbooks. One specialist can improve the environment used by many builders, much as a common road or supply system increases the mobility of every corps that depends on it.</p><p>The arrangement only works if shared expertise does not recreate the handovers that smaller teams were meant to remove. The builder should continue to own the result, bringing specialists into the work when their judgement is needed rather than sending the work away and waiting for it to return. Shared teams provide direction, reusable capability and help with difficult exceptions, while the team of one retains the ability to move.</p><p>Teams of one will not replace every team because complex, long-lived systems with many users, dependencies and stakeholders carry too much risk, context and organisational negotiation for one person, who may also become a dangerous single point of failure. Even so, the boundary will move as small teams take on work that once required departments, with each person directing a software corps of their own. As these units become smaller and faster, the limiting factor shifts from their ability to produce code to the organisation’s ability to let them act.</p><h3>Speed of command</h3><p>Napoleon’s corps moved quickly because they could act without waiting for headquarters at each step, which meant that faster marching was merely the visible expression of faster command. The same is true for software, where a team of one is useful only when the builder can move from decision to production without crossing half the organisation. Waiting weeks for access, a platform team, a security committee and a monthly deployment window gives you faster coding without faster delivery.</p><p>Moving decisions closer to the builder does not mean removing control. It means placing the safe means of action inside the unit, so agents have defined missions, the context required for the task and clear limits on what they may change. Stable interfaces, automated tests and observable systems allow them to act within those limits, while rules for escalation tell them when to stop and ask a human.</p><p>Without those boundaries, autonomy becomes guesswork. An agent told to improve performance might change a cache, rewrite a database query or remove a check it considers redundant, even though each option carries a different operational risk. A better instruction explains the desired outcome, protects the invariants that must survive and requires evidence that the change works under realistic conditions.</p><p>A useful specification becomes a form of commander’s intent because it describes the desired outcome, the constraints and the evidence that will count as completion. The agent can then respond when the repository differs from the plan without inventing its own policy.</p><p>Tests matter for the same reason. They are no longer only a way to detect mistakes after code has been written, but a machine-readable expression of what the organisation expects to remain true. Logs, traces and metrics extend that expression into production by showing whether the system continues to behave as intended. Together, they give the builder a fresher picture of reality and allow agents to correct problems before those problems climb through several layers of management.</p><p>The freedom to move should follow the consequences. An internal tool used by five people can travel faster than national identity infrastructure, just as a prototype using synthetic data needs less supervision than a service making decisions about people’s lives. The controls should become stronger as data sensitivity, reach and possible harm increase, without forcing low-risk work through the same obstacle course.</p><p>This makes the foundations of mobility unusually important. Safe development environments, controlled access, shared standards, automated policy checks and paved routes to production allow a builder to move without negotiating every step from the beginning. Older systems must also be legible enough for agents to work on them without guessing, and responsibility must remain with a person.</p><p>The platform becomes the equivalent of roads, maps and supply. It gives each small unit access to approved infrastructure, handles routine security requirements and records what was changed. When this works, governance happens as part of delivery instead of arriving as an inspection at the end. When it does not, each builder must rediscover the organisation’s rules, request the same permissions and wait for the same specialists, which recreates the old system around a faster source of code.</p><p>There is therefore a large difference between asking AI to produce something that looks right and creating the conditions in which one person can direct several agents, move quickly and remain accountable after the system reaches production. The second requires engineering standards, operational discipline and clear ownership long after the first demonstration is over.</p><p>The engineer’s job becomes harder because writing a function from a clear requirement may take minutes, while discovering that requirement in a tangle of policy, user behaviour and old systems still demands judgement. The same judgement is needed to decide what an agent may change and to recognise when a locally sensible answer creates a larger failure. The work resembles command more than typing, and a good programmer will not automatically be good at it, just as the best person with a musket was not automatically the best corps commander.</p><p>Napoleon’s battlefield manoeuvres get the paintings while logistics and staff work rarely do, and software demonstrations have the same bias because watching an agent generate an application in seven minutes is more fun than discussing identity controls and deployment policy. Yet the spectacular part depends on the boring part, and the ability to sustain speed matters as much as the ability to achieve it.</p><h3>When the advantage disappears</h3><p>Napoleon’s advantage did not last. After years of defeat, his opponents copied the corps system, improved their staffs and learned to coordinate their armies. They stopped attacking him piecemeal and began denying him the battles he wanted. What had looked like military magic became the standard way to fight.</p><p>Russia exposed another weakness. In 1812, Russian armies kept retreating as Napoleon advanced deeper into the country, stretching his supply lines until the system that had carried him across Europe began to consume itself. His army could still move, but it could no longer sustain the movement. Speed without support had become a faster route to disaster.</p><p>AI coding will travel through the same cycle. Models will improve, agent techniques will spread and the clever workflows of today will become features in tomorrow’s development platforms. Soon, access to an excellent coding agent will be as unremarkable as access to cloud computing. Having one will tell us very little about what an organisation can do with it.</p><p>This is why demonstrations can be deceptive. Two organisations may use the same model and produce equally impressive prototypes, yet one can release a safe service in days while the other spends months negotiating access, ownership and approval. The difference appears after the code is generated, in the machinery that turns an experiment into a system somebody can rely on.</p><p>The advantage will come from collapsing the distance between intent and action. A capable builder should be able to understand a problem, direct a corps of agents, release the solution and learn from production without pushing the work through an obstacle course of handovers. Governance must travel with the team, built into its tools and boundaries, because controls that sit elsewhere eventually become queues.</p><p>Organisations that make this change will turn small teams into forces far larger than their headcount suggests. Those that preserve structures built for scarce engineering capacity will produce more code and wonder why nothing else became faster.</p><p>Napoleon’s opponents eventually acquired his corps, although learning how to move took them longer. Soon everyone will have the agents. The organisations that move will decide what happens next.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=68bd5521fb79" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>