❌

Reading view

Anthropic's Opus 5 is about token efficiency, not a capability leap

Today, Anthropic rolled out Opus 5, the newest update for the model that has recently become a popular choice for coding and other software development tasks, among other things.

While this is a noteworthy bump for Opus, it doesn't seem to be an Opus 4.5-level breakthrough in agentic coding performance.

Read full article

Comments

© Anthropic

  •  

Model Context Protocol is going stateless to make scaling simpler

Model Context Protocol (MCP), the emerging standard for connecting AI models to external tools and enterprise data, is undergoing its biggest architectural overhaul yet.

The latest release candidate, scheduled for release on July 28, removes protocol-level sessions in favor of a stateless architecture, a change which industry experts say is intended to make MCP easier to deploy across standard cloud infrastructure as enterprises move AI pilots into production.

“The session-based model made sense when MCP servers were local processes on a developer’s laptop. In production, it became an operational tax,” said Muskan Bandta, cloud associate at ZopDev.

“When your infrastructure team asks whether MCP services can scale like other cloud applications, the answer used to be ‘not quite.’ With the move to a stateless architecture, the answer is now yes,” Bandta added.

Earlier versions of the protocol maintained information about every client connection, meaning servers had to keep track of each session throughout an interaction. While that approach worked well for local development, it complicated deployments across multiple servers because requests often had to be routed back to the same machine, limiting scalability and making MCP a less natural fit for modern cloud architectures.

“Under the new stateless design, every request contains the information needed for any available server to process it independently. Applications that need to maintain context across multiple requests can still do so, but developers must now manage that state explicitly rather than relying on the protocol itself,” she said.

This transition to a stateless design goes beyond simplifying infrastructure by fundamentally changing how AI applications manage and share context across tools, according to Amit Jena, AI development manager at IT consulting firm Kanerika.

Instead of keeping application state hidden inside protocol sessions, the new design makes it explicit, allowing AI models to access, reason over, and pass that information between tools, giving developers greater control over how context is preserved and shared across tools, Jena said.

It should also make AI workflows more portable, resilient, and easier to orchestrate across distributed environments, he said.

MCP’s new features

Other changes to MCP include the addition of a Multi Round-Trip Requests (MRTR) mechanism that changes how AI agents request additional information they need to complete a task.

Instead of relying on a persistent connection between the client and server throughout the interaction, the new mechanism lets the server request additional input through a standard request-response exchange before continuing the task, Jena said.

Routable transport headers, another addition, enable API gateways and other networking infrastructure to identify and route MCP requests without inspecting their contents.

They reduce processing overhead, lower latency, and let enterprise teams enforce routing, rate-limiting and security policies more efficiently using existing API management infrastructure, Jena said.

MCP is also getting an updated authorization framework built around OAuth 2.1 and OpenID Connect; interactive MCP Apps; and deterministic caching of tool and resource listings to improve LLM prompt-cache hit rates, potentially saving on token costs.

Rebuilding the trust boundary

The MCP release steering committee also decided to deprecate some legacy features, including Roots, Sampling, Logging, the older HTTP+SSE transport and Dynamic Client Registration, although these will continue to work in this version and any other released over the next year.

The deprecation of Sampling is likely to have the biggest impact because it changes who is responsible for interacting with foundation models, said Jena.

“Sampling let MCP servers invoke the LLM through the client, which meant the server had a callback path into the model without owning that connection. Deprecating it means rebuilding that trust boundary,” Jena said. “Your server now calls the model provider directly. That changes your network architecture, your auth model, and depending on how you’ve built cost attribution, your billing flow.”

The year-long transition period will be enough for teams to audit their sampling dependencies now, said Jena: “The risk is that teams who haven’t implemented sampling themselves won’t know if a third-party MCP server they’re depending on uses it.”

Updated MCP SDKs

To accompany the protocol update, there are updated MCP SDKs for Python, Typescript, Go, and C#. These support both the old and new protocol versions, so new clients can continue communicating with older servers, while updated servers will also support older clients, reducing the risk of immediate disruptions.

That backward compatibility should make the transition largely incremental, except for enterprises that built custom infrastructure around MCP’s earlier session-based architecture, Bandta said.

Identifying and auditing those session dependencies may not be easy, Jena warned.

“Session management complexity tends to be hidden across multiple layers — the gateway config, the deployment scripts, the monitoring dashboards. The code change is small; finding everywhere the assumption lives is what takes time,” he said.

  •  

Top AIs invent same fake PyPl and npm package names

Enterprise software developers continue to be in danger of falling victim to slopsquatting, where AI coding tools hallucinate the existence of nonexistent libraries and hackers create malicious packages in response.

The top AI coding tools are remarkably consistent in their hallucinations: Researcher Aleksandr Churilov found the same 127 fake package names generated by five different LLMs.

Slopsquatting is a relatively new form of malware attack that involves the creation of malicious packages in response to the hallucinations of AI coding tools, causing the malicious packages to be incorporated into legitimate applications.

Churilov set out his findings in a research paper, The Range Shrinks, the Threat Remains: Re-evaluating LLM Package Hallucinations on the 2026 Frontier-Model Cohort, which is yet to be peer-reviewed. He found 127 hallucinated package names were shared across Claude Sonnet 4.6, Claude Haiku 4.5, GPT-5.4-mini, Gemini 2.5 Pro, and DeepSeek V3.2.

 As of April this year, 53 of those names — 41 on the PyPI software repository and 12 on npm —are still available for registration.

According to the study, there are two reasons for this amount of conformity in the output of the models. First, models may learn the same incorrect package references from shared public training material, such as tutorials and documentation.

Second, they may independently extrapolate plausible names from ecosystem conventions. In this way, they could produce names that look correct, even if they don’t actually exist.

While Churilov’s research will worry CISOs and security-conscious developers, there is some relief. The research has not yet found any evidence that any of the remaining 53 names have been registered maliciously, nor used in an attack.

  •  

The Microsoft agent framework wars are over. The real architecture decision starts now

Over the past year, I had the same conversation with almost every team starting an AI initiative. Should we build on Semantic Kernel, AutoGen or Foundry?

At first it felt like the most important architectural decision we’d make. Each framework had its own philosophy, each promised to be the foundation for enterprise AI, and picking the wrong one felt like an expensive mistake. I spent a lot of time helping teams weigh the trade-offs.

Looking back, I think we were asking the wrong question. I certainly was.

I watched teams spend months debating SDKs while the decisions that actually decided whether their applications survived production went unexamined. Some built elaborate orchestration layers for workflows that a few deterministic functions would have handled. Others avoided agent frameworks entirely and later found they’d designed themselves into a corner.

Then Microsoft settled it for us. It introduced the unified Agent Framework, quietly moved Semantic Kernel and AutoGen into maintenance mode, and the debate I’d spent months refereeing was suddenly over. Turns out the answer to “which of the three” was “none of the three, here’s a fourth.” The framework hit version 1.0 and general availability in April 2026, stable across .NET and Python.

What surprised me wasn’t the decision. It was how fast a debate that had eaten so much of our attention stopped mattering. Microsoft changed the menu.

It didn’t change the meal.

The framework was never the hard part

Framework selection dominated almost every early conversation I had about enterprise agents. Which SDK do we standardize on? Which orchestration model gives us the most flexibility? Which one is Microsoft actually betting on?

Fair questions. But after a year of watching these projects play out, I’ve slowly come around to a different view. Those weren’t the questions that decided anything.

The first question I ask now is much smaller. Does this thing actually need an agent?

It sounds obvious, and I still get it wrong sometimes. But it’s the mistake I see most. On one project, a team spent weeks designing a multi-agent workflow for a process that ran the same four steps every time: read a document, validate it, call an API, send a notification. The diagrams looked great. The system in production didn’t. A few well-tested functions would have been easier to build, easier to maintain and a lot easier to trust.

Part of this is just that “agent” has become the word everyone reaches for. Sometimes it’s the right call. Sometimes it’s a workflow we already knew how to build, wearing a newer label. An agent earns its complexity when it genuinely has to decide things you can’t predetermine, choosing between tools, adapting to what it finds, working out its own next step. If you already know every step, you have a workflow, and a workflow is usually the better engineering choice. The consolidation didn’t change that. It just made it easier to see.

What building production agents actually taught me

Once I stopped fixating on frameworks, the same three problems kept showing up. None of them had anything to do with the SDK.

Context beats model choice

Early on I spent a lot of time comparing models, the way you’d agonize over a restaurant menu and then order what you always order. Now I spend most of it thinking about context, which is far less fun and far more useful.

I’ve watched good models fail because they were handed too much, not too little. One team I worked with gave the model access to nearly every internal document they had on the theory that more information meant better answers. It went the other way. Responses got slower, less consistent and sometimes skipped right past the thing that actually mattered. When we cut the context down to only what the task needed, the quality jumped almost immediately. I didn’t predict that. It taught me to be suspicious of “just give it everything.”

The best agent systems I’ve worked on weren’t the ones with the biggest context windows. They were the ones careful about what reached the model, and when. That’s not something the framework hands you.

Failure is where the real work is

Most agent demos look great because they’re built around the happy path. Production doesn’t extend that courtesy.

I remember a project where everything held up in testing. Then a downstream API timed out after the agent had already completed several earlier steps. We couldn’t just restart, because part of the business process had already gone through. We ended up spending far more time on recovery logic than we ever spent on prompts. That project changed how I think about this work. The hard part was never getting the model to make a decision. It was making sure the system didn’t fall apart when reality refused to follow the script.

Tool calls fail partway through. APIs return inconsistent data. Models call the same tool over and over because the last answer wasn’t what they wanted. That’s not the exception; that’s a normal Tuesday. Whether you retry, roll back, pause for a human or push on with partial results is a judgment call, and no framework is going to make it for you.

Identity is the real security boundary

This one surprised me most. The moment an agent stops being a chatbot and starts touching real business systems, identity matters more than orchestration.

Every project gets to the same question eventually. Who is this agent actually acting as? The developer’s credentials? A service account? The user who asked? Get it wrong and you’ve built something autonomous running with more access than any single person should have, which is exactly the kind of thing that looks fine until an audit. The Agent Framework, like most modern tooling, makes it easier to wire agents to tools through standards like the Model Context Protocol. That helps. But where human approval belongs, what needs extra authorization, how much rope to give the thing, those are still yours to decide.

The surprises weren’t technical

Here’s what I didn’t see coming. The hardest part of last year wasn’t technical at all. It was organizational. The moment a team heard “agent,” expectations shifted under everyone’s feet. Business stakeholders started expecting full autonomy. Developers assumed the thing could reason its way through anything. People started designing for flexibility before we’d even agreed on what problem we were solving. The word did damage before any code did. I found myself spending as much time resetting expectations as I did discussing architecture.

Build for change, not for today’s winner

I don’t think the teams that struggled last year picked the wrong framework. Semantic Kernel was reasonable. AutoGen was reasonable. Foundry made sense for plenty of cases. I’d have signed off on any of them.

The ones that got hurt put all their eggs in one framework, treating it as the foundation of the whole system instead of as one more dependency. Microsoft provided a migration path. But teams that had tightly coupled their applications to framework-specific abstractions discovered that migrating and rewriting are not the same thing. That wasn’t Microsoft’s doing. It was their own architecture’s. The teams that moved easily had kept their business logic, prompts and orchestration loose enough to evolve independently of any one SDK. For them, the change was a manageable project, not a teardown.

For what it’s worth, nobody I work with is treating this as an emergency. Most are moving the smaller workloads first, watching how they behave and leaving the production-critical systems alone until they actually understand the new abstractions. That’s the right instinct. And I doubt this is the last consolidation we’ll see, the ecosystem is still young, frameworks will keep absorbing each other and over time the differences between them will be operational more than architectural.

I don’t regret the framework debates, honestly. They were reasonable at the time. What changed wasn’t Microsoft’s roadmap.

It was mine. Watching these systems run in production taught me that the framework is the easiest piece to swap out. Recovery logic, context management, security boundaries, the business workflow itself, those stay with you long after today’s SDK gets replaced by tomorrow’s.

So, Microsoft made one decision easier by turning three frameworks into one. Good. Five years from now we’ll be on different tools, and we’ll still be asking the same handful of questions.

Does this actually need an agent? Does it have the right context? Can it recover when something breaks, because something will? Is it acting as the right person?

Those questions outlast every rewrite. That’s where I’ve learned to put my effort.

Frameworks come and go. Good architecture has to survive all of them.

This article is published as part of the Foundry Expert Contributor Network.
Want to join?

  •  

How to execute queries in parallel using EF Core

EF Core is Microsoft’s flagship ORM (object-relational mapper), the software layer that allows .NET developers to work with relational databases. The DbContext class is the core component of the EF Core framework for managing database operations. However, the DbContext class in EF Core is not thread-safe. Hence, if you share DbContext instances between multiple threads, you will often encounter data corruption issues and the InvalidOperationException.

In this article, we’ll learn how we can execute queries in parallel in EF Core by handling thread-safety issues to avoid concurrency errors. To work with the code examples provided in this article, you should have Visual Studio 2026 installed in your system. You can download Visual Studio 2026 here.

Executing EF Core queries in parallel – the problem

When working in today’s data-driven applications, you will often need to fetch data from multiple unrelated datasets. In applications that use concurrency, thread-safety is critical to guaranteeing correct execution, avoiding data corruption and race conditions, and ensuring data consistency. Let’s understand this with an example.

Let’s say we want to populate a dashboard that displays all recently processed orders, metrics, logs, and traces, as well as your application’s performance metadata. We might write the following code.

public class Dashboard
{
    public List Orders { get; set; } = new();
    public Metrics Metrics { get; set; } = new();
    public List Logs { get; set; } = new();
    public List Traces { get; set; } = new();
}
public static async Task LoadDashboardAsync(ProductService productService)
{
    Task<List>    ordersTask  = productService.GetProcessedOrdersAsync();
    Task        metricsTask = productService.GetMetricsAsync();
    Task<List> logsTask    = productService.GetRecentLogsAsync();
    Task<List>    tracesTask  = productService.GetTracesAsync();
    await Task.WhenAll(ordersTask, metricsTask, logsTask, tracesTask);
    return new Dashboard
    {
        Orders  = await ordersTask,
        Metrics = await metricsTask,
        Logs    = await logsTask,
        Traces  = await tracesTask
    };
}

In the preceding code snippet, there are four read operations that are executed by four different Task instances. Our objective is to ensure that the database round trips run in parallel instead of in sequence. We can accomplish this by usingTask.WhenAll, which starts the four tasks, waits for every task to finish, then returns the data wrapped inside a new Dashboard instance.

If we executed these queries sequentially, the user would have to wait until each query completed its execution in turn—for a total wait time equal to the sum of the times for all four queries. However, by running these queries in parallel, we reduce the wait time considerably. The user will need to wait only as long as it takes for the slowest of the four queries to complete its execution.

However, there is a danger with the above approach. If you run multiple operations on the same DbContext instance, you will see an InvalidOperationException with the following message:

A second operation started in this context before the previous operation was completed. This is usually caused by multiple threads using the same DbContext instance; instance members are not guaranteed to be thread-safe.

Databases such as SQL Server, PostgreSQL, and Oracle Database follow a request-response communication model at the connection level: a single connection can process only one command at a time. Hence, you cannot run multiple queries concurrently using the connection. If you await several operations using the same connection, EF Core detects the overlapping use of a non-thread-safe context and throws an InvalidOperationException. To run queries in parallel, you must give each task its own connection or context.

Why DbContext isn’t thread-safe – and how to work around it

The DbContext class in EF Core is designed to manage a single unit of work. To be more precise, EF Core does not provide support for running multiple operations on the same DbContext instance. This design approach creates inherent challenges when you use the same DbContext instance across multiple threads. If DbContext were thread-safe, extensive locking would be required, which would degrade data access performance.

This stateful design of DbContext makes it unsuitable for concurrent access patterns that involve loading, modifying, or tracking different sets of data simultaneously, because it needs to maintain the internal representation of database state.

The change tracker is one of the most important components of DbContext in EF Core. It monitors all entities loaded into memory and detects any changes made to them after they have been loaded. It keeps track of the original, current, and changed values of the entities, thereby enabling the EF Core runtime to know the current state of these entities when you call the SaveChanges() method on the DbContext instance.

To implement thread-safety when working with DbContext, we must write our code to ensure that each concurrent operation gets its own copy of a short-lived instance. Now, we could accomplish this by wrapping a shared DbContext instance inside a thread-safe block using the lock keyword, so that all calls to the database take place using one and only one thread at a time. This approach is illustrated in the code snippet below.

using Microsoft.EntityFrameworkCore;
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; } = string.Empty;
    public decimal Price { get; set; }
    public int Quantity { get; set; }
}
public class AppDbContext : DbContext
{
    public AppDbContext(DbContextOptions options) : base(options) { }
    public DbSet Products => Set();
}

However, while the above approach gives us the thread-safety we need, it can degrade data access performance considerably. A better approach is to use IDbContextFactory , which creates fresh DbContext instances on demand. Calling its CreateDbContext() method is cheap and produces a fresh, isolated context every time.

The following code snippet shows how you can register an instance of type IDbContextFactory as a singleton. You can safely call this code from any thread.

builder.Services.AddDbContextFactory(options =>
    options.UseSqlServer(
        builder.Configuration.GetConnectionString("Default")));

Executing EF Core queries in parallel – the solution

Now let’s see how we can put IDbContextFactory to work. The following code illustrates a class named ProductService that uses a factory to create DbContext instances for each scope of work.

public class ProductService
{
    private readonly IDbContextFactory _factory;
    public ProductService(IDbContextFactory factory)
        => _factory = factory;
    public async Task GetByIdAsync(int id)
    {
        await using var context = await _factory.CreateDbContextAsync();
        return await context.Products.FindAsync(id);
    }
    public async Task UpdateStockQuantityAsync(int id, int updateQuantity)
    {
        await using var context = await _factory.CreateDbContextAsync();
        var product = await context.Products.FindAsync(id);
        if (product is null) return;
        product.Quantity += updateQuantity;
        await context.SaveChangesAsync();
    }
}

Note that ProductService has two methods, GetByIdAsync and UpdateStockQuantityAsync. An instance of the DbContext class is created locally in each of these methods. Now, suppose you have two threads, T1 and T2, that execute these methods concurrently. That is, thread T1 executes the GetByIdAsync method while thread T2 executes the UpdateStockQuantityAsync method. Because each of these methods is executed in isolation, they will have their own context, connection, and change-tracking information, and there will be no mutable state, so you don’t need to implement thread synchronization in either of these methods.

Consider the following code that executes a read operation and an update operation in two separate tasks.

public static async Task RunMethodsInParallelAsync(ProductService productService)
{
      Task readTask = productService.GetByIdAsync(1);
      Task updateTask = productService.UpdateStockQuantityAsync(3, 5);
      await Task.WhenAll(readTask, updateTask);
      Product? product = await readTask;
 }

The Task.WhenAll method runs the two tasks in parallel and waits until both have finished. The reason this approach is thread-safe, and will not create concurrency errors, is that each of these two methods creates its own DbContext instance internally. Therefore the read operation and the update operation use independent DbContext instances.

Use DbContext pooling to reduce allocation cost

Although creating DbContext instances is not that costly, you should consider using pooled contexts in applications that require high scalability and high performance. The following code snippet shows how you can register a pooled context.

builder.Services.AddPooledDbContextFactory(options =>
    options.UseSqlServer(connectionString));

A call to AddDbContext() will register a DbContext instance as scoped per HTTP request. Each request will run on a different thread and each will have its own context. However, keep in mind that the default scoped registration of the DbContext will not always suffice.

You will need a factory to create instances of DbContext when you’re using a background service, or performing some work inside a particular request, or running some business logic operation over multiple contexts.

Key takeaways

  • If you use EF Core in the data access layer of your application, you must implement thread safety measures whenever you run your queries in parallel.
  • You cannot execute multiple queries in parallel in EF Core using the same DbContext instance.
  • The IDbContextFactory enables you to create a DbContext instance for each thread, thereby enabling you to work with these instances in isolation.
  • Although using a DbContext pool involves a small allocation overhead, it becomes a non-issue if you need high throughput.

  •  

Visual Studio Code 1.130 dresses up Agents window

Microsoft has released Visual Studio Code 1.130, an update to the code editor that brings several improvements to the Agents window, along with enhancements to the agent host and the terminal.

VS Code 1.130 was released on July 22, one week after VS Code 1.129. Developers can access the release for Windows, Linux, or Mac from code.visualstudio.com.

With the new release, the Agents window gets updates that make it easier to review changes and manage chats. File-level diff statistics help users assess the size of each file’s changes when scanning a multi-file diff. The window also gets a more compact multi-file diff that makes it easier to review changes, Microsoft said. The Agents window is a dedicated window in VS Code that lets users run and track multiple agent sessions in parallel across their projects, without opening each workspace in a separate window.

Also with VS Code 1.130, assisted permissions for agent tool calls are available in the agent host. With assisted permissions, the LLM evaluates the risk of each tool call and decides whether the tool can run or should require the user’s approval. The setting to enable assisted permissions is chat.assistedPermissions.enabled. In another agent host improvement, quick chats running on the agent host now use compact, single-line rows in the sessions list. Regular sessions retain a second line with change statistics, status, and timestamps.

VS Code users now can open file links from Git diff output in the terminal when Git’s diff.mnemonicPrefix option is enabled. VS Code recognizes prefixes such as i/ for the index and w/ for the working tree, and removes the prefix from the link target so the correct file opens. When mnemonic prefixes are enabled, VS Code also recognizes the numeric prefixes produced by git diff --no-index.

Timestamps for chat requests and responses now are displayed when users hover over the message toolbar. You can disable this through the chat.verbose setting.

  •  

New pip flag fixes longstanding Python frustration

A new version of Python’s native package management tool, pip, will remove a limitation that has frustrated Python developers for years. If you wanted to install the dependencies for a given package, but not install the package itself, you were stuck. Either you had to extract the dependency list from the package and install it by hand, or you had to build the whole package anyway.

Why was this a problem? Sometimes, you want only the dependencies for a package—for instance, as a way to create a separate environment for testing or another project. If you’re making source distributions via CI, some requirements might be needed to make the source distribution but aren’t actually included in it (e.g., Cython). You would need to install these requirements somewhere—apart from the project itself—to perform the build step.

A dependencies-only install mode for packages is a long-requested feature. Developer James O’Claire found many examples of such requests, along with various workarounds. Most of those involved third-party solutions of some sort.

Now, a new feature set to land in pip version 26.2 will fix this problem from the inside. The command pip install --only-deps will install only the dependencies for a given package. Note that it will not install build dependencies for the package, but only runtime dependencies.

Note that you can accomplish this with existing third-party tools. For instance, uv sync --no-install-project has the same behavior. But having this functionality right inside pip means you don’t have to turn to external tooling—or ugly hacks—to solve the problem. This may be an example of how third-party projects like uv (a superfast Python package installer) are inspiring native Python features where they make sense.

pip 26.2 is scheduled to be released by the end of July 2026.

  •  

WSL container: A quiet revolution for Windows development

Running containers on Windows has never been as easy as it should be. While there are versions of Docker Desktop and Podman that work with both the Windows Subsystem for Linux (WSL) and Hyper-V, I’ve found both overly complex and unstable. Where they have worked, it’s turned out that Hyper-V has been the best option, using a Linux virtual machine to host my containers. That all adds up to overhead, layers of virtual infrastructure that get in the way of work and that need to be rebuilt every time I restart my PC.

Part of the problem is WSL. It’s a good tool, but WSL2’s file-system integration is slow, and you’re left having to work with code using Visual Studio Code’s remote integration, which means putting a VS Code Server in every container you’re building and testing. If you’re working with Kubernetes, that’s even more complexity that needs to be managed, dragging you away from code.

I ended up running most of my container testing and development from a separate machine, a Linux server running containerd. But though it worked (and had all the resources of workstation-class device), it wasn’t portable, and for some reason I’ve yet to uncover, Ubuntu’s remote desktop access doesn’t work for me.

So, it was good to see Microsoft make several announcements around WSL at Build 2026 as part of a push to make Windows a developer platform again. The first, an improved WSL3, is still some way away, but the second, WSL-native container support, shipped at the end of June. It is already seeing community-driven development of Docker Desktop-like tooling to help monitor and manage your containers.

Delivering a WSL-based container platform fits in with the other developer-focused Windows announcements at Build. Making Windows behave more like Linux is Microsoft responding to developer needs, given that more than 50% of servers on Azure run a Linux distribution. Linux is the basis of cloud-native infrastructure, so developers need to be able to build on it wherever they are.

Getting started with WSL container

WSL container provides a new CLI that works in parallel to the familiar WSL, with commands to support the entire container life cycle, from creation to shut down. All you need to do to get started is upgrade your WSL installation to the current pre-release build (at the time of writing this was 2.9.3). Simply open an administrator PowerShell terminal and enter wsl --update --pre-release.

This downloads and installs the latest WSL release. Once you’ve closed and re-opened your terminal (to ensure that you’ve updated its context) you can check that WSLC has installed by entering wslc, which should list the available commands. The new CLI is aliased to WSL container, if you prefer to keep your container work separate from WSL (and avoid typos that might accidentally affect your WSL installations).

Under the hood Microsoft is using WSL container to trial new integration points for Linux in Windows. One key change is the use of a new file system that significantly speeds up access to Windows from inside a container. Another improvement gives WSL container a new networking mode that relays networking connections directly through the Windows network stack, ensuring it has access to the same resources and security as Windows.

Calling Linux containers from Windows applications

Things get more interesting when you start to use the WSL container API from inside your Windows code. Here you can include calls to Linux containers inside your desktop applications, taking advantage of existing services, building and deploying containers from inside your CI/CD pipeline. Using the new file system and networking stack helps reduce the friction that comes with crossing the boundaries between the two platforms.

The WSL container API is available as a NuGet package, with support for C, C#, and C++. It allows your code to start and stop containers, and interact directly with them, sending command-line calls and reading back responses. Where things get interesting is being able to launch a containerized service from your code, exposing its REST or gRPC APIs on a local network port. Microsoft has provided sample code to show you what’s possible at this early stage.

Microsoft is doing something revolutionary here. It’s taking the cloud-native, service-driven model and bringing it into Windows and using it to bridge decades of divergent development. You no longer have to rewrite a service that works on Linux to run in Windows; all you need to do is containerize the service and launch it from the WSL container API. When you’re done, the API will tidy up after you, shutting down the container and reclaiming the memory it used.

It’s important to remember that this is only the first public preview of a rapidly developing platform. There are many opportunities here to, say, build on the syscall translation layer developed for WSL1 to produce a native Windows-to-Linux application integration stack that removes the overhead of using web-based service calls. It will be interesting to see what develops, but this first release is very interesting indeed.

Manage Linux containers from Windows

If you want a Docker Desktop-like experience for building and testing containers on Windows developer hardware, you may not have long to wait. WSL container’s underlying API is already being used to build tools that manage and monitor containers for you. One such tool is the WSL Container Desktop, under development on GitHub. While there aren’t any release builds yet, it’s easy enough to compile and get running by cloning the source repository and building using the .NET CLI. You do need to have the Windows App SDK installed, and some features require access to the Azure CLI.

WSL Container Desktop is built in C#, with a WinUI front end. It’s currently only verified for use on x64, though I was able to compile and run it on an Arm64 PC and use it to test and run containers. Once running, it gives you a well-designed front end for your WSL-hosted containers, showing what’s running and what resources they are using. You can link WSL Container Desktop to container registries, like Docker’s and Azure’s, so you can quickly pull base containers and then use the WSL container environment to add your own code and customizations.

Your main interaction point is the WSL Container Desktop dashboard, which shows what containers are running and their current resource usage. Elements are displayed in cards, taking a cue from Windows’ own user interface and especially from its Settings app. From the dashboard, you can drill down into the available containers, with quick start, stop, and reload options, as well as an extended memory that includes the ability to open a web browser to the appropriate port. I tested this with a container that included an entire KDE webtop, giving me a Linux distro running in a container in my browser.

Other options include a details view that displays current logs and provides tools for inspecting the state of a container. This is the type of tool that comes in useful when debugging and testing container applications, as it can provide insights that the WSL container CLI doesn’t offer. Another option helps you clean up after you’ve downloaded an image and don’t need it anymore, with analytics that show the largest images and images you haven’t used for some time. On top of its tooling for working with WSL containers, WSL Container Desktop provides a basic settings tool that helps you configure its look and feel, as well as how it integrates with Windows.

Run Kubernetes inside Windows for cloud-native development

One of the more useful features of WSL Container Desktop is the ability to quickly stand up a K3s Kubernetes instance in WSL that can be used to host WSL containers, providing a local environment to build and test cloud-native applications wherever you might be. The K3s tooling offers a similar experience to the Kubernetes project’s own Headlamp UI, making it easy to go between your development environment and a production Kubernetes cluster.

It’s fair to describe WSL container as one of those Windows features you didn’t think you needed, but now it’s here you can’t live without it. WSL container simplifies building a container development tool chain in Windows, and at the same time allows you to think about a new generation of hybrid applications that take advantage of decades of development in both Windows and Linux.

The result is something that was unimaginable a few years ago: dropping a Linux container into the middle of a Windows application and treating it as another local service. As the WSL container platform evolves, you should expect to see more ways of bringing Linux and Windows together, using containers to deliver a hybrid platform that gives us the best of both worlds at long last.

  •  

Determining the ROI of AI requires data that most companies lack

Leadership wants to scale AI. Budgets are tripling. Adoption is up.

Then the CFO asks the question every board now asks: which of these initiatives is actually profitable?

Most organizations cannot answer that question, not because they lack visibility into cost, but because the cost data they have was never designed to produce that answer.

Applying lessons learned from managing cloud spend won’t be a fix for the AI and ROI quandary. True, cloud taught a generation of CFOs that billing without business context is noise. So to get cloud ROI, they stitched two data sources together: cost data plus business data. AWS reveals which account, which region, which tag, which resource. Merge in customer and product mappings on top and the ROI of the cloud spend comes into focus.

But AI is harder. It requires three data sources: cost, business, and telemetry—the automatic collection of data from disparate sources that helps to clarify the whole picture of what happened and why. An executive or engineering lead can have AI invoices and customer revenue. But they have no way to connect them to business value. The token count on the OpenAI invoice does not specify which customer triggered which call, which feature it served, or whether the prompt produced a business outcome. That data does not exist in the provider’s billing.

AI providers won’t fix this problem

The situation is not likely to change anytime soon because AI providers are not in the business of attributing an enterprise’s costs to that enterprise’s customers. Instead, AI providers are in the business of selling tokens. The granularity they expose is the granularity their billing systems require, not the granularity a CFO requires.

Not convinced? Compare what AWS gives you to what an AI provider gives you.

AWS billing exposes resource IDs, account hierarchies, region, SKU, tag metadata, usage by the minute. Every dollar can be attributed to a workload, a team, a customer segment if it was tagged correctly. The data is rich enough that mature FinOps teams built unit economics on top of it years ago.

An AI provider invoice gives you tokens consumed by model, with optional grouping by API key. That is the resolution. No request-level attribution. No customer ID. No feature mapping. No prompt outcome. No retry identification. Multi-step agent workflows collapse into a token count. Imagine a large bank receives a multi-million dollar AI invoice each month. But it has no visibility into what parts of the business were responsible for what parts of the cost so cannot allocate them.

If an enterprise wants to know what AI cost drove which customer or feature, it has to capture that data itself, inside an application, before the call leaves it. 

Three required sources

Building AI ROI measurement requires three data sources, stitched together in a single model.

  1. Cost data, normalized across providers. Every AI provider delivers cost differently. OpenAI invoices in one taxonomy, Anthropic in another, fine-tuning vendors and inference platforms each in their own. Cloud GPU costs sit in AWS or Azure billing. Vector database costs land in Pinecone or Snowflake invoices. None interoperate by default. Normalization is necessary but not sufficient. It will put all your AI costs in one schema. It does not tell you what they produced.
  2. Application-layer telemetry. This is the source most organizations are missing, and the one that makes AI ROI structurally different from cloud ROI. It requires instrumenting AI calls inside your application across six categories: request-level tracing tied to a customer or session ID; feature attribution tied to the product surface that triggered the call; agent-step capture for multi-step workflows; retry and fallback identification so recovery costs don’t get attributed to primary calls; model selection logging that records which model was chosen and why; and outcome capture that ties each call to whether it produced business value. None of this data exists in the provider’s billing. All of it has to be captured at the moment the call is made and stored in a system that can be stitched to the cost data.
  3. Business data. Revenue, customer segments, product hierarchies, and feature usage. The same business data already feeding your CRM and analytics stack, mapped to the customers and features the telemetry layer attributes calls to.

Stitched together, the three sources produce the unit economics every AI investment decision now requires: cost per customer interaction, margin per feature, profitability per agent workflow, ROI per model choice. None of these can be calculated from billing data alone. None can be calculated from telemetry alone. They require all three sources, modeled together in a way that maps cost to outcome.

Why agentic AI makes this urgent

Single-call inference is the easy case. One request, one cost, one customer, one outcome.

Agentic workflows are different. An agent decomposes a task into multiple steps. Each step calls a model. Some steps fall back to a different model when the first fails. Some steps retry on a poor result. Some steps invoke external tools that themselves cost money. A single user request can produce dozens of inference calls across multiple providers, with the cost compounding in ways the provider invoice cannot disaggregate.

If telemetry does not capture agent-step granularity, no one will know which steps are profitable. Aggregate costs will show up three weeks later in the invoice. By then, the workflow has been running at scale, customers are onboarded, and unprofitable paths have been retried thousands of times.

When agents make the calls, the volume of cost-generating events without business context attached grows by an order of magnitude. The window for instrumenting this before it becomes unmanageable is closing.

What changes when the three sources come together

Once the three sources are stitched together, the AI investment conversation changes.

Five different ways to build the same AI capability stop looking equivalent. They converge on adoption metrics and diverge by 10x on cost. The team picks the approach that delivers a similar business outcome at one-fifth the cost, because the team can finally see the difference. Product teams design features with margin awareness from the architecture phase, not from the post-launch budget review. Engineering teams choose model architectures with cost-per-outcome data alongside latency and quality. Leadership evaluates AI initiatives the way they evaluate any other capital allocation: on unit economics, not on the engagement chart. Aggregated invoices track the cost per customer interaction. Engagement metrics reveal margin per feature. Gut-instinct model selection is checked against real cost-per-outcome model selection results. 

Within seconds, everyone can see which AI features are profitable, which should scale, and which should be killed. This is the insight everyone is looking for and companies that achieve it will optimize the benefits of AI.

The build trap

AI costs are compounding now. The board is not waiting 18 months for an internal project to reach production.

The temptation to build it anyway has never been sharper. AI coding tools have changed what a small engineering team can ship in a quarter. The instrumentation layer looks tractable. The cost normalization looks like a weekend project. The semantic model feels like something a senior engineer could draft over a sprint.

It is a trap. Three reasons.

Volume is the first. A production AI footprint generates millions of telemetry events per hour, and that volume scales with agentic adoption. Real-time ingestion, correlation, and attribution at that scale is not the same problem as vibe coding a prototype in an afternoon. It is a permanent operational system that has to be right every minute of every day.

The vendor landscape is the second. Cost data arrives in delayed billing windows from providers with non-interoperable schemas. Schemas change without notice. New AI providers enter the landscape monthly, each with its own taxonomy and metering. The system is not built once. It is maintained against a moving target that moves faster than most internal release cycles.

The third is what the first two add up to: this is business-critical infrastructure. The CFO and the board are going to make capital allocation decisions on the data this system produces. When schema drift goes unnoticed for two weeks, when an agent telemetry stream stops correlating to a vendor that quietly changed its billing API, the cost of being wrong is not a sprint of cleanup. It is a quarter of misallocated capital.

The build-vs.-buy question for engineering leaders has changed. It’s not “can we build this?” The honest answer is yes. The real question is whether the marginal hour of your strongest engineers is best spent stitching cost data to telemetry to business outcomes, or building the AI products that produce the revenue the cost data is measuring.

The capability is reproducible in weeks. The choice is whether to spend the next 18 months building it, or the next 18 months acting on it.

—

New Tech Forum provides a venue for technology leaders—including vendors and other outside contributors—to explore and discuss emerging enterprise technology in unprecedented depth and breadth. The selection is subjective, based on our pick of the technologies we believe to be important and of greatest interest to InfoWorld readers. InfoWorld does not accept marketing collateral for publication and reserves the right to edit all contributed content. Send all inquiries to doug_dineley@foundryco.com.

  •  

G# language for .NET borrows from Go, Kotlin, and Swift

G# (GSharp) is moving forward as a programming language for Microsoft’s .NET platform, touted as bringing Go-, Kotlin-, and Swift-style ergonomics to the CLR (Common Language Runtime). The language is described by its creators as modern, simple, and accessible.

Although pre-1.0 and still growing, G# aims to be for people who want a small, predictable language with direct access to the .NET ecosystem. Developers will see imports, func, structs, slices, maps, channels, go, select, and for in iteration. Also important are nullable flow, direct calls into the CLR (Common Language Runtime), and built-in concurrency.

With G#, copyrighted in 2026, developers get value-oriented structs, reference-oriented classes, data structs, and data classes. For concurrency, G# uses scope for structured concurrency, async func and await for task-based asynchrony, and async sequence[T] for asynchronous streams. G# also makes use of the same Task and Task[T] types familiar from the .NET BCL (Base Class Library).

G# documentation is available on the GitHub site of Microsoft software engineer David Obando. “Every .NET type—your packages, third-party NuGet packages, the BCL—is callable from G# with the syntax you already know. CLR generics use G#’s bracket spelling, and method calls, properties, indexers, and for in over IEnumerable[T] all just work,” according to the website.

A Visual Studio Code extension for G3 can be found at marketplace.visualstudio.com. The extension adds syntax highlighting, language server features, build/run commands, and debugger configuration for .gs and .gsproj files. Developers can install the extension from within VS Code (search for “G#” in the Extensions view) or from the command line.

  •  

Cisco’s new AI model tells code reviewers where to look for vulnerabilities

Cisco has revealed a family of open-weight AI models called Antares that, it said, can help security teams isolate potentially vulnerable parts of a software repository before deeper investigation begins.

Rather than detecting a specific CVE or generating a patch, these models search a codebase using only a Common Weakness Enumeration (CWE) description and return the files most likely to contain that class of vulnerability.

“Its purpose is to reduce a large codebase to a focused set of files that a security professional or a downstream security workflow should investigate,” Cisco’s AI researcher Supriti Vijay said via email. “The goal is not to replace a security engineer’s judgement or send them on a wild-goose chase, but to reduce fatigue and workload by helping them triage an issue earlier and focus their investigation on the most relevant parts of the codebase.”

The Antares family consists of models with 350 million, 1 billion, and 3 billion parameters trained specifically for repository-scale vulnerability localization.

The company said its largest model approaches the performance of GPT-5.5 on its internal vulnerability localization (Vloc) benchmark while remaining small enough for low-cost local deployment.

A search assistant, not a vulnerability detector

Cisco is careful to define what Antares is, and what it is not.

“Antares outputs a ranked list of source files likely to contain a relevant vulnerability, along with the terminal exploration trace that led to that result,” Cisco Foundation AI Chief Scientist Amin Karbasi wrote in a blog post, adding that the models are not meant to replace the broader application security toolchain: Human analysts or downstream security tools will still be needed to confirm exploitability, identify vulnerable lines of code, assess severity and generate fixes.

Antares differs from conventional static analysis platforms such as Semgrep or CodeQL, which primarily rely on predefined rules or queries. Cisco instead describes Antares as an evidence-driven exploration agent that adapts its search as it traverses the repository.

Cisco’s argument is that large repositories often contain thousands of files, making manual reviews exhaustive and unrealistic. By reducing the search space to a manageable shortlist, the company hopes to reduce investigation fatigue without replacing human judgement.

Claims of specialization over scale

Cisco is also making a statement about how cybersecurity models should evolve.

Instead of pursuing larger foundational models, Cisco argued that specialized, task-trained models can outperform much larger open-weight alternatives for vulnerability localization. In its evaluation Antares-3B, the largest model intended for single-GPU deployments, produced results comparable to GPT-5.5 while outperforming several substantially larger open models by Google, OpenAI and Meta.

The family also includes Antares-350M for resource-constrained environments and Antares-1B for laptops and workstations, which Cisco has made available as open-weight models on Hugging Face.

The command line interface (CLI) on the models supports targeted CWE investigations, repository-wide scans, SARIF output and local inference, which Cisco said enables organizations to keep proprietary code inside their own trust boundary.

However, because Antares identifies candidate files rather than confirmed vulnerabilities, organizations will still need to understand how often such repository-wide searches should be run, how much they improve existing triage workflows, and whether the reduction in investigation effort ultimately translates into measurable security or cost benefits.

  •  

GitLab previews auto-remediation of vulnerable dependencies

GitLab has released GitLab 19.2, an update to the company’s devsecops platform that allows teams to fix vulnerable dependencies automatically, use Security Review Flow to catch logic flaws that scanners miss, and run AI agents straight from the terminal, the company said.

Highlights in GitLab 19.2 include the following:

  • Dependency Scanning Auto-Remediation, in public beta, uses AI to fix build-breaking changes and iterates until your pipeline passes, with every change governed by your existing gates and audit trail.
  • Security Review Flow, also in public beta, analyzes code changes as a security engineer would and catches authorization gaps, business-logic errors, and race conditions that static scanners structurally cannot see.
  • GitLab Duo CLI, now generally available, gives developers access to agents and multi-step agentic flows for all software life cycle tasks without leaving the terminal. 
  • Custom Flows, now generally available, let teams replace manual multi-step workflows with agentic automations for software development, triggered by GitLab events.

“Coding agents made it possible to generate far more code and moved the bottleneck downstream to reviews and security,” said Manav Khurana, chief product and marketing officer at GitLab, in a statement. “GitLab 19.2 puts agents to work on that bottleneck: fixing vulnerable dependencies, catching the flaws scanners miss, and automating the steps in between with a person still approving what ships.”

  •  

Agentic coding is everywhere

I use a very cool and relatively new web framework called Astro. The keen insight that the Astro team had was that most websites are made up of static content, so they made it really easy to add content to a website. To add a blog post to my personal website, all I have to do is create a Markdown file with some front matter, deploy it, and the blog post automatically appears. If I need to reach deeper for more dynamic functionality, I can easily do that with TypeScript, React, or almost any other framework. It’s really cool.

And these days, I really don’t write any code. Claude Code does most (all?) of the work. Since Astro is an open-source project and has excellent documentation, Claude knows all about how Astro works. It has no trouble at all managing my site and making the improvements I ask for.  

And that got me thinking, how does Astro get built? Is the Astro team building with agentic coding? Astro itself has many dependencies, including big projects like Vite and Node. And of course, Vite and Node have dependencies, too. Are those dependencies being developed by hand, or are those development teams also using AI agents to code?

My curiosity got the best of me, and I asked Claude to dig deeper. It turns out that the Astro repository has an AGENTS.md file, and some of the commits even have commit message trailers indicating that they were at least co-authored by Claude and GitHub Copilot. Further down, there is a .agents/skills directory with skills covering development, merging, triage, and more. I poked around for a look, and someone has done a great job building agentic support.

Now my interest is really piqued, and further investigation reveals quite a bit of interesting stuff. About a year ago, documentation started appearing about how to build Astro sites with coding agents.  Around that same time, the docs team released an MCP server that gives developers coding agents deeper, easier access to the Astro documentation.  

And there are small steps in the Astro codebase that indicate it is “agentic ready.” For instance, the command-line development server can tell when it is being started by an agent, and the application itself can tell if it is being driven by an agent. Small things, but steps in the direction of embracing Astro developers who use coding agents. 

Okay, that was a fun spelunking trip. But so what?

The “so what” is that code is going to be commoditized. As an Astro developer I am using AI agents pretty much all of the time. The Astro development team is starting to use AI agents more and more. The folks building the Astro dependencies are using AI agents. Shoot, the people building Claude Code and the agents themselves are “eating their own dogfood” and using their own tools to build the next frontier model. Before we know it, it will be turtles all the way down. 

No one says “who generated that electricity?” or “who wove the fabric in that shirt?” any more. And it won’t be long before no one says “Who wrote the code for that app?” because it won’t matter. Just as we don’t look at the assembly code written by our compilers, we’ll stop looking at the “regular” code written by our agents. I’m not even sure anyone is writing assembly code anymore. Soon we’ll be saying that about TypeScript, Python, and C++.

  •  

Seven sins of the modern software developer

If you ask us in an official setting, our official position is that software engineering norms still apply. Rigorous CI/CD pipelines, elegant architectural patterns, and an unyielding commitment to maintainable code remain the standard. We will use weighty words like “determinism,” “scalability,” “idempotency,” and “domain-driven design.”

But behind closed doors, late at night, bathed in the glow of a dark-mode IDE, a different and more sordid reality is exposed. Hunched over the console with a manic gleam in the eye, the programmer has become power-drunk on LLMs. Like mad wizards casting spells, we summon the awesome powers of models and agents to satisfy our every programming whim—and commit acts of software engineering that would make Fred Brooks blush.

Let’s just be honest about what is actually happening.

Esoteric knowledge is superfluous

Forget OOP and FP. Forget the CAP theorem, the holy crusade of DRY, and the design patterns. Honestly, you can even forget what frameworks, runtimes, and deployment platforms you are using. The AI will figure out what is best to use and understand what is already in place. We have more mental bandwidth for working on our side project (a novel about AI taking over the world). 

Of course, I exaggerate. A little.

The docs are dead to us

We still say RTFM, but the truth is, we haven’t really read a page of vendor documentation since 2023. Stack Overflow, once our Internet Mecca, is a husk. When a package throws a weird exception, we don’t trace the execution path or read the release notes. We highlight the red text, copy the entire 200-line stack trace, dump it into the chat, and wait for the machine to spoon-feed us the solution.

Better yet, we just have the agentic IDE spot the error, divine a solution, and ask us if it’s OK. We might glance at the problem-solution description, if we have gone around the circle on the problem for a few cycles. Maybe. If we don’t have the agent set up for auto-confirm.

We used to buy heavy tomes like “Rust In Action” that were more like masonry blocks than literature. Now? We just ask an AI to transliterate our JavaScript logic into Rust. We are no longer engineers methodically learning a system. We are glorified copy-paste orchestrators hoping that the stochastic parrot behind the prompt guesses the syntax correctly.

We ignore how the back end is wired

We act like we meticulously designed the data flows, carefully crafted the relational constraints, and mindfully mapped the API relationships. The reality is rather more disturbing: We asked the AI to scaffold a modern deployment, hooked it up to a back-end database, and just sort of… ran it.

It created security rules we don’t fully understand. They do seem to work, however, which is nice. 

It generated a schema that we skimmed for about four seconds. It looks reasonable.

It wrote infrastructure-as-code scripts that provisioned cloud resources we are hoping don’t blow a hole in the budget. Presumably, whoever is in charge of that will manage it by stuffing the metrics into another chatbot.

We nodded, committed the code, and went to lunch. If management asked us to manually deploy the stack from scratch, configure the environment variables, and wire the API routes without our chat window, we would give them a vacant stare.

We understand that management is also using AI to manage the project.

Our tests are uncomfortably incestuous

Test-driven development (TDD) used to be a beautiful dream, ever just beyond reach. It made us feel glorious and despondent at turns. It would burden us with sprawling dependencies if implemented too religiously. (See The Grug Brained Developer in this regard.)

But now we can attain 95% test coverage almost effortlessly. Why not just add them in while we are auto-generating everything else?

We can now wax at length to anyone who will listen about our astounding test coverage and our automated quality assurance. Unit tests, integration tests, smoke tests, you name it. What we conveniently leave out is that the AI wrote the complex application logic, and then we asked the exact same AI to write the test suite to validate the code it just dreamed up.

It is a hermetically sealed loop of algorithmic self-congratulation. The mocks, the edge case, and the assertions are an echo chamber of the model’s original assumptions. The machine is grading its own homework, giving itself an A+.

And we are happy to accept this because, beautifully, when the code has to change, the AI will effortlessly hallucinate new tests to adapt to the churn.

We pass off the AI’s architecture as strategy

AI can produce astonishing design documents. Truly breathtaking. They are cogent, they’re beautifully formatted, and they seamlessly bridge the gap between high-level business goals and granular technical specs. They even include those auto-generated sequence diagrams that wow management.

When we present these spotless architectural proposals in the Tuesday sprint planning meeting, we lean back, take a long sip of coffee, and humbly wave away the team’s praise.

What we don’t mention is that we spent exactly four seconds generating it.

Are these AI-generated documents just as liable as human ones to hide severe, mortal flaws in scope and alignment? Absolutely. They might contain a foundational logic bomb that will eventually doom the entire project. But the markdown is so crisp, and the bullet points are so persuasive, that the eye just glides right over it. We will never truly know the depth of the disaster until it is far too late. But hey, we’ll burn that bridge when production catches fire. Until then, we are strategic visionaries.

We’re addicted to vibe coding (but only in secret)

We loudly mock the term on social media. We roll our eyes in Slack channels when the kids on TikTok talk about vibe coding their new startups. We fiercely cling to our identities as hardened, serious developers who understand memory management, garbage collection, and bitwise operators. We are professionals, damn it.

But late at night, when the managers are asleep and no one is looking? We absolutely love it. We love just throwing a chaotic, half-baked thought at the canvas, pouring a drink, and watching the AI magically build a functioning user interface based entirely on our long-deferred whims. I may finally build that working Ultima V clone. The thrill of typing “Create an app that tracks my cryptocurrency portfolio but makes it look like the interface from Neuromancer” and having it appear 30 seconds later is heady stuff.

The more deeply rooted in the hard, old-school realities of programming, the more profound is the joy the developer finds in the possibility of AI coding. 

We beat the problem into submission with prompts

Like Adam Sandler in “Uncut Gems,” we are convinced the next round will fix everything. This is us with prompts. When things are going really off the rails, instead of putting our boots on and wading into the brambles of complexity, we resort to tonal adjustments. These range from the condescending:

This problem is not fixed. Look at it closely. The error is right here.

To the desperate:

We have been working on this same problem for hours now!

To the pathetic:

Can’t you find a different approach to try?!

The astonishing part? It often works.

But there is no poetry left at the bottom of the rabbit hole; it is verbal warfare. When the context window collapses, when the regressions start cascading, and when the AI stubbornly refuses to follow the most basic rules of temporal logic, the mask of professionalism drops away and something far more atavistic makes its appearance. We stop asking nicely, stop trying to understand the why, delete the pleasantries, and capslock our intent.

What we have here is a failure to communicate!

We feed the same failing stack trace back into the prompt over and over and over again, aggressively hammering the constraints, explicitly forbidding certain libraries, and pasting in release notes just to confirm that the AI lacks the latest APIs. We force the model down a narrower and narrower path until the code finally stops throwing errors. We don’t actually debug anymore, trace variables, or step through functions. We just apply relentless, iterative pressure until the machine surrenders. We beat it into submission. And then, we push to production.

In fact, there is a real skill here—a sheer “will to completion” that remains in the act of building software. We invest just as much time, energy, and heart wrestling the bot as we ever did emitting syntax.

A blacker box

The only profession more given over to using AI like a cursed Level 13 artifact than programming is writing. Writing of course is far more open to public scrutiny than code.

And while my tongue has been firmly in my cheek here, my faith in coders as good guys makes me more curious to see what we create than troubled by the dangers. 

It was once the case that only other programmers could understand what programmers were doing, what they were producing. Now not even that is true. Only the machine knows what the machine is doing. We just keep it tethered to our aims. Hopefully.

  •  

Visual Studio Code 1.129 introduces dedicated agent host

Microsoft has released Visual Studio Code 1.129, an update to its free, popular code editor that features a dedicated agent host and an editor panel in the Agents window. The updated editor also allows users to run terminal commands from chat prompts with a !prefix and offers a preview of a modern UI for the workbench.

Released July 15, VS Code 1.129 can be downloaded from code.visualstudio.com for Windows, Linux, and Mac.

Microsoft is rearchitecting how agent sessions work in VS Code around the agent host — a dedicated process that runs agent harnesses such as Claude, Copilot, and Codex, based on the Agent Host Protocol (AHP). Since a session lives in its own process, the same session can be connected to and rendered from multiple VS Code windows at once. The agent host’s Copilot agent is powered by the Copilot SDK, which means that its behavior and functionality is aligned with the Copilot CLI, the standalone GitHub Copilot app, and other Copilot products. The agent host is being rolled out to users in the editor window and the Agents window. It’s enabled through the chat.agentHost.enabled setting.

The Agents window shows conversation with an agent next to a detail area for the files and changes it produces. This release introduces a redesigned editor panel that brings the editor and the detail area together into one docked pane with a shared tab bar, so reviewing an agent’s work feels like working in the main editor instead of switching between separate panels.

Other new features and improvements in VS Code 1.129:

  • Users now can prefix chat messages with a ! to run their contents as terminal commands. This works in agent host sessions, both in the editor and in the Agents window.
  • Developers can now use Bring Your Own Key (BYOK) models in the Agents window when selecting the Copilot harness running on the agent host.
  • Developers can preview a modernized VS Code UI that updates the look and feel of the editor workbench. This is currently an experimental feature that can be enabled with the workbench.experimental.modernUI setting.

VS Code 1.129 follows Visual Studio Code 1.128, released July 13. An update, VS Code 1.129.1, fixes three bugs including remote agent hosts failing to start.

  •  

‘The Java Story’ recounts the rise, fall, and rise again of Java

The evolution of Java is the subject of a just-released documentary about the programming language and development platform. “The Java Story: The Official Documentary” tells the story of Java through interviews with the engineers who created it and shepherded it through three decades.

Produced by CultRepo and sponsored by Oracle, JetBrains, IBM, and Azul, the documentary follows Java from its set-top box and browser-based origins at Sun Microsystems in the 1990s and through its rise to dominate server-side computing in the 2000s, the “dark ages” and resurgence with Java 8 under Oracle in the 2010s, and its continuing modernization and promising role in AI today. “From its humble beginnings as a project code-named ‘Oak’ at Sun Microsystems to becoming a global standard for enterprise software and billions of devices, Java’s journey is one of radical innovation, strategic pivots, and enduring community strength,” said Cult.Repo.

The documentary also delves into Sun’s bitter Java licensing dispute with Microsoft, Oracle’s suit of Google over its use of Java APIs Android (Google won), the creation of the Java Community Process, Sun’s open-sourcing of Java, and Oracle’s switch to the six-month release cycle. Technical enhancements such as lambda expressions in Java 8, virtual threads in Java 21 (Project Loom), and the ongoing refactor to bring value objects to the Java object model (Project Valhalla) also get attention.

Technical experts and other Java figures interviewed in the documentary include James Gosling, creator of Java; Kim Polese, Java’s first product manager; Carla Schroer, director of Java compatibility at Sun Microsystems; James Duncan Davidson, creator of Apache Tomcat; Mark Reinhold, chief architect of the Java Platform Group at Oracle; Brian Goetz, Java language architect in the Java Platform Group at Oracle; Rod Johnson, creator of Spring; and Gavin King, creator of Hibernate.

  •  
❌