Possible software supply chain attack through AWS CodeBuild service blunted 15 Jan 2026, 10:19 pm

An AWS misconfiguration in its code building service could have led to a massive number of compromised key AWS GitHub code repositories and applications, say researchers at Wiz who discovered the problem.

The vulnerability stemmed from a subtle flaw in how the repositories’ AWS CodeBuild CI (continuous integration) pipelines handled build triggers. “Just two missing characters in a regex filter allowed unauthenticated attackers to infiltrate the build environment and leak privileged credentials,” the researchers said in a Thursday blog.  

The regex (regular expression) filter at the center of the issue is an automated pattern-matching rule that scans log output for secrets and hides them to prevent leakage.

The issue allowed a complete takeover of key AWS GitHub repositories, particularly the AWS JavaScript SDK, a core library that powers the AWS Console.

“This shows the power and risk of supply chain vulnerabilities,” Yuval Avrahami, co-author of the report about the bug, told CSO, “which is exactly why supply chain attacks are on the rise: one small flaw can lead to an insanely impactful attack.”

After being warned of the vulnerability last August, AWS quickly plugged the hole and implemented global hardening within the CodeBuild service to prevent the possibility of similar attacks. Details of the problem are only being revealed now by Wiz and AWS.

AWS told CSO that it “found that there was no impact on the confidentiality or integrity of any customer environment or AWS service.” It also advised developers to follow best practices in using AWS CodeBuild.

But the Wiz researchers warned developers using the product to take steps to protect their projects from similar issues.

Discovery

Wiz discovered the problem last August after an attempted supply chain attack on the Amazon Q VS Code extension. An attacker exploited a misconfigured CodeBuild project to compromise the extension’s GitHub repository and inject malicious code into the main branch. This code was then included in a release which users downloaded. Although the attacker’s payload ultimately failed due to a typo, it did execute on end users’ machines – clearly demonstrating the risk of misconfigured CodeBuild pipelines. 

Wiz researchers investigated and found the core of the flaw, a threat actor ID bypass due to unanchored regexes, and notified AWS. Within 48 hours, that hole was plugged, AWS said in a statement accompanying the Wiz blog.

It also performed additional hardening, including adding further protections to all build processes that contain Github tokens or any other credentials in memory. AWS said it also audited all other public build environments to ensure that no such issues exist across the AWS open source estate.

In addition, it examined the logs of all public build repositories, as well as associated CloudTrail logs, “and determined that no other actor had taken advantage of the unanchored regex issue demonstrated by the Wiz research team. AWS determined there was no impact of the identified issue on the confidentiality or integrity of any customer environment or any AWS service.” 

Kellman Meghu, chief technology officer at Deepcove Cybersecurity, a Canadian-based risk management firm, said it wouldn’t be a huge issue for developers who don’t publicly expose CodeBuild. “But,” he added, “if people are not diligent, I see how it could be used. It’s slick.” 

Developers shouldn’t expose build environments

CSOs should ensure developers don’t expose build environments, Meghu said. “Using public hosted services like GitHub is not appropriate for enterprise code management and deployment,” he added. “Having a private GitLab/GitHub, service, or even your own git repository server, should be the default for business, making this attack impossible if [the threat actors] can’t see the repository to begin with. The business should be the one that owns the repository; [it should] not be something you just let your developers set up as needed.” In fact, he said, IT or infosec leaders should set up the code repositories. Developers “should be users of the system, not the ultimate owners.” 

Wiz strongly recommends that all AWS CodeBuild users implement the following safeguards to protect their own projects against possible compromise.”

  • Secure the CodeBuild-GitHub connection by:
    • generating a unique, fine-grained Personal Access Token (PAT) for each CodeBuild project;
    • considering using a dedicated unprivileged GitHub account for the CodeBuild integration.

(image/jpeg; 35.72 MB)

Gleam update shines on external types 15 Jan 2026, 8:48 pm

Gleam 1.14.0, a new version of the statically typed language for the Erlang VM and JavaScript runtimes, has enhanced support for external types.

Released December 25, the update can be accessed at GitHub. With this release, the @external annotation is now supported for external types, giving the programmer a way to specify an Erlang or TypeScript type definition to be used, according to Gleam creator Louis Pilfold. Gleam’s external type feature is used to declare an Erlang or JavaScript type that can be referenced in Gleam, but because the type originates from outside of Gleam, the Gleam compiler cannot produce a precise definition in generated Erlang or TypeScript type definitions. Instead, the compiler had to fall back to the correct but vague “any” type of each language.

Also enhanced in Gleam 1.14.0 is inference-based pruning, an optimization that improves performance and detects more redundant patterns when pattern matching on binary data. Gleam 1.14.0 extends this optimization to work with int segments, thus increasing its effectiveness.

Gleam 1.14.0 also offers number normalization in pattern matching analysis, resulting in faster code. Numbers can be written in different formats in Gleam (decimal, octal, hexidecimal, etc., or scientific notation could be used to represent floats). The compiler now internally normalizes these values to a single canonical representation. This representation now is used by the pattern matching analysis engine, further enabling optimizations such as interference-based pruning.

Other improvements in Gleam 1.14.0:

  • Equality testing has been made faster. Performance of == and !=has been improved for field-less custom type variants when compiling to JavaScript.
  • The record update syntax now can be used in constant definitions, enabling constant records to be constructed from other constant records.
  • The release updates to the latest Elixir compiler API, fixing some warnings that would be emitted with previous versions of Gleam and the latest version of Elixir.

(image/jpeg; 5.19 MB)

When your platform team can’t say yes: How away-teaming unlocks stuck roadmaps 15 Jan 2026, 10:00 am

Product teams regularly approach platform organizations with requests that make complete business sense. A team launching in new markets needs regional payment processor integration. Another team piloting a new discounting strategy needs a new incentive construct. A third team building an enterprise offering needs custom invoicing capability. These requests are well-scoped and clearly valuable. Yet platform teams must frequently decline them, not because the request lacks merit, but because the platform roadmap is already full of other higher-priority features and capabilities.

Product teams, meanwhile, operate under different constraints. Revenue targets do not adjust for platform capacity. Market launch dates were set months ago. Pricing experiments that could move key metrics cannot wait two quarters for platform prioritization.

This familiar impasse stalls innovation, forces product teams into costly duplication and pits business priorities against engineering reality. While various collaboration models exist (Team Topologies describe interaction modes, or embedded platform experts), these assume the platform team either has capacity to prioritize the work or that product teams should proceed independently.

Away teaming offers a different, resource-neutral mechanism: product teams temporarily assign engineers to build what they need as reusable platform capabilities, under platform guidance. This is the viable way out of the zero-sum game.

Why conventional approaches fail

Platform teams face a resource equation that never balances. Demand consistently exceeds capacity by substantial margins. As a platform engineering leader I receive 3 to 5 times more requests than my team can fulfill in any given quarter.

The standard responses all produce poor outcomes:

  • Product teams wait. They miss launch windows. Competitors ship first. The carefully planned go-to-market strategy becomes irrelevant because the timing is wrong.
  • Product teams build independently. Within months, the organization accumulates duplicated effort: multiple, incompatible implementations of pricing logic, custom invoicing systems that generate reports in incompatible formats and a spiderweb of technical debt that platform teams will eventually have to reconcile at 3 times the original cost.
  • Platform teams accommodate everything. They deliver neither their critical roadmap work nor the product requests well. Engineers burn out. Technical debt compounds. The platform becomes increasingly fragile under the weight of rushed implementations.

The zero-sum framing (platform priorities versus product needs) ensures someone always loses.

How away-teaming restructures the problem

Away teaming inverts the traditional model. Instead of platform engineers embedding with product teams to provide expertise, product engineers temporarily join platform teams to build required capabilities under platform guidance.

This is fundamentally different from the established patterns described in Team Topologies or standard platform collaboration models. While the ‘X-as-a-Service‘ mode assumes the platform team has capacity to fund and build the service, and the ‘Facilitating‘ mode assumes capacity to coach, away teaming addresses the specific scenario where the platform team’s capacity is effectively zero for new feature work, but still has capacity for governance.

Consider an enterprise product team that needs custom invoicing capabilities. The platform team could not prioritize this work. Instead, two engineers from the product team joined the platform team for 8 weeks. Working under platform guidance, they built a general-purpose invoicing service. The product team got their enterprise invoices on schedule. The platform gained a reusable invoicing capability. Four months later, when another product team needed invoicing capability, they could use the same invoicing service. What would have been separate implementations became a single platform capability serving multiple products.

The new resource equation

The product team assigns engineers for a defined period, typically 6 to 8 weeks. These engineers work in the platform codebase, attend platform standups, follow platform coding standards and receive guidance from platform engineers.

Product teams have already secured funding for their initiatives. Away teaming redirects that investment from building a product-specific solution into creating a reusable platform capability.

For platform teams, this expands effective capacity without headcount growth. Platform engineers provide design review, answer questions and conduct code review. They use their expertise without spending execution capacity on implementation work. The platform gains capabilities it could not have funded while maintaining quality standards and consistency.

Establishing the foundation: Essential prerequisites for success

Away teaming is not simply a collaboration technique. It requires specific organizational conditions to function effectively.

1. Executive alignment is critical

This cannot succeed as a platform team initiative alone. Product and platform leadership must jointly commit to the model.

When product teams miss OKRs because engineers were away teaming, product VPs need to view that as an acceptable tradeoff, not a failure. If the VP of product does not openly champion this model, product managers will be incentivized to hoard their engineers, seeing away teaming as a resource drain rather than a strategic investment. The model will die quietly through non-participation.

To successfully pitch this to product leadership, frame the ‘resource loss’ not as a temporary cost, but as a strategic investment in technical risk mitigation. By temporarily funding a reusable platform capability, the product VP is eliminating the 3x reconciliation cost and high-risk technical debt associated with their team building it independently. This protects future velocity and product stability across the organization.

2. The career development framing matters enormously

Product engineers need to view away teaming as a growth opportunity, not a sacrifice.

Frame it explicitly as platform engineering experience that builds broader systems thinking skills and deepens architectural understanding. In organizations that excel at this, an away team assignment is seen as an important point for a Senior Engineer promotion, signaling that the organization values cross-cutting, reusable systems over purely product-specific velocity.

3. Clear governance prevents drift

Someone must decide which requests become away team engagements. Establish a joint platform-product review process that evaluates requests against specific criteria:

  • Does the capability serve multiple future products?
  • Can the platform team provide meaningful guidance?
  • Is the product team willing to accept reduced velocity during the engagement period?

These prerequisites are not optional. Get executive buy-in first. Everything else depends on it.

Execution mechanics: A guide to running away team engagements

Start with a scoping conversation involving both team leads and the engineers who will do the work. Three elements need explicit documentation:

  • The business value the product team must deliver.
  • The platform standards the work must satisfy.
  • The support the platform team will provide.

If any of these three elements cannot be articulated clearly, the opportunity is not suitable for away teaming.

Temporary team membership

Away team members join the platform team operationally. They attend standups, work in platform codebase and receive code review with the same rigor applied to any platform work. This is not a contractor relationship; it is temporary team membership.

However, their connection to their home team remains protected. Regular synchronization with product leadership validates that the work addresses actual requirements.

Guidance, not project management

The platform team provides guidance rather than project management. Platform engineers answer questions about service boundaries and system design, conduct design review and pair on complex challenges. They do not track tasks or manage sprint planning.

Guidance takes real time. Code review for unfamiliar engineers takes longer. A platform team supporting two concurrent away team engagements should expect to spend roughly 10–15 hours per week of senior engineer time on guidance. This is the investment that makes the model work.

Knowledge transfer is non-negotiable

Before an away-teaming engagement concludes, at least one platform engineer must become the ongoing owner of that code. This requires:

  • Documentation that explains the why (alternatives considered, tradeoffs made).
  • Sufficient test coverage.
  • Operational runbooks for production issues.

Away team members typically present their work to the broader platform organization. This ensures the platform team actually understands what they will be maintaining.

Impact & accountability: Measuring success and learning from failure

Away teaming requires measurement to remain credible.

  • Track capability reuse. Aim for capabilities that are adopted by two distinct products (beyond the originating team) within six months of creation. If these capabilities serve only their original product team, the generalization effort fails.
  • Monitor product team velocity impact. A team losing two engineers for eight weeks should expect 15-20% reduced output. If the impact significantly exceeds this, the away team members are either more critical than anticipated or the product team is understaffed.
  • Track engagement outcomes. What percentage of away team engagements deliver working capabilities that meet platform standards? If this falls below 80%, examine common failure modes like insufficient technical depth or inadequate platform support.

When away teaming fails, acknowledge it quickly. Not every engagement will succeed. Failed engagements provide valuable learning about what works and what does not.

When away-teaming does not apply

Some capabilities are too foundational to delegate. Core payment processing that touches every transaction, the base pricing model or revenue recognition logic that must satisfy regulatory requirements all require direct platform ownership even if other work must be delayed.

Away teaming works best for capabilities in the middle ground: too product-specific for immediate platform prioritization, yet general enough that future products will benefit from reuse.

Away teaming also has scale limits. A platform team might effectively support two concurrent away team engagements. Beyond that, guidance capacity becomes strained.

The compounding benefits

The direct value is apparent: platform capabilities that could not otherwise be funded get built. But the secondary effects often prove more valuable:

  • Platform advocacy: Product engineers who complete away team assignments become platform advocates. They understand the architectural tradeoffs and can credibly explain platform limitations, reducing tension and frustration between teams.
  • Distributed capability: These engineers help their product teams use platform capabilities effectively, spot opportunities for future platform work and design features that integrate cleanly with platform services.
  • Compounding capability: Each capability built through away teaming (e.g., custom invoicing, promotional discount engines) becomes available for future products, multiplying the platform’s overall utility.

Platform teams maintain focus on foundational work. Total platform capability expands substantially beyond what direct funding could achieve.

Getting started

Organizations implementing away teaming should begin with one pilot. Choose a product team with a clear platform need and a collaborative orientation. Document how it works, what both teams commit to and how success will be measured. Get explicit executive sponsorship from both platform and product leadership.

The conversation with product teams transforms immediately.

Rather than “we cannot prioritize this,” platform teams propose: “We cannot fund this capability, but you can. Is this important enough to invest engineering bandwidth for a defined period?”

This reframes platform dependency from a blocker into a tractable investment decision that product teams evaluate against their priorities.

Here is the reality that most platform organizations struggle to accept: you will never have enough people to build everything that should be built. Away teaming is not a compromise; it is the funding model that turns a resource constraint into a catalyst for decentralized, reusable capability growth. It is how platform organizations achieve scale while maintaining quality and consistency.

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

(image/jpeg; 7.45 MB)

Getting started with GitHub Copilot in Visual Studio or VS Code 15 Jan 2026, 9:00 am

The way software is developed has undergone multiple sea changes over the past few decades. From assembly language to cloud-native development, from monolithic architecture to microservices, from manual testing to CI/CD automation, we’ve seen the emergence of numerous software architectures, technologies, and tools to meet the ever-changing demands of enterprises and their developers.

Most recently, AI-powered tools have impacted software development dramatically. One such tool is GitHub Copilot, a powerful and accessible AI pair programmer that integrates seamlessly into Visual Studio and Visual Studio Code.

In this article, we’ll cover what GitHub Copilot is, why it matters, and how you can use it to generate and optimize code inside Visual Studio. We’ll also examine how GitHub Copilot can fix issues in your code and even help you test it.

What is GitHub Copilot and why do we need it?

Modern software development thrives on speed, accuracy, and innovation. Developers often spend a lot of time writing boilerplate code, integrating APIs, or debugging issues in the source code. Now with the emergence of AI and AI-powered tools and technologies, you can automate all of these time-consuming tasks to boost developer productivity.

GitHub Copilot is an AI-powered coding assistant that can generate code, optimize code, document code, fix issues, create tests, draft pull requests, and enable developers focus on creative, complex problem-solving tasks. GitHub Copilot, which supports models from OpenAI, Anthropic, Google, and others, is much more than a code autocompletion tool. It uses advanced AI models to understand natural-language comments and the context around your code, generate code snippets, automate repetitive tasks, reduce errors, and speed up your software development workflow.

While traditional autocompletion tools suggest code based on syntax, GitHub Copilot understands the purpose of your code, i.e., what the code is intended to accomplish, and generates entire code blocks or code snippets as needed. As a result, developers can be more productive and consistent, and write better code by adhering to the best practices and identifying and fixing issues and bugs early.

How does GitHub Copilot help software developers?

Here are a few ways GitHub Copilot can help you as a developer:

  • Boost productivity: GitHub Copilot can write boilerplate, repetitive, or verbose code in seconds. Hence, you can stay focused on building the architecture, writing business logic, and writing data access code rather than spending your time on mundane tasks.
  • Reduce cognitive load: GitHub Copilot can automate tasks, help write complex business logic, and reduce the need for context switching, reducing cognitive load and helping to prevent burnout.
  • Write efficient code: Using natural-language prompts, developers can generate readable, structured, modular, and consistent code. GitHub Copilot can also help with refactoring, bug fixing, and enforcing best practices.
  • Facilitate faster learning: Beginners and experienced developers alike can learn new libraries, APIs, or frameworks faster from the live examples GitHub Copilot generates.
  • Enhance testing and validation: GitHub Copilot can help you generate tests, explore edge cases, provide remedies, and fix issues in your code.

Install GitHub Copilot in Visual Studio

To install GitHub Copilot using the Visual Studio Installer, follow the steps outlined below.

  1. Launch the Visual Studio Installer.
  2. Choose the installation of Visual Studio you want to use.
  3. Click Modify to launch the next screen to modify workloads as shown in Figure 1.
  4. Select the workload you want to modify.
  5. Select GitHub Copilot and click Modify to start the installation.
Visual Studio Installer - GitHub Copilot

Figure 1

Foundry

This will install GitHub Copilot and integrate it inside your Visual Studio IDE. You can also install GitHub Copilot in Visual Studio Code, but we’ll use Visual Studio here. Whether you’re using Visual Studio or Visual Studio Code, getting started with GitHub Copilot is quick and easy.

Generate code using GitHub Copilot

You can use GitHub Copilot to generate new code giving it instructions in natural language. Just right-click in the code editor inside Visual Studio, click on “Ask Copilot”, and type an instruction. For example, you could ask Copilot to generate code to display all prime numbers between 1 and 100, as shown in Figure 2.

GitHub Copilot generate code

Figure 2

Foundry

Fix bugs in your code using GitHub Copilot

GitHub Copilot can also help fix bugs in your code. Let us understand this with a simple example. Refer to the following code.

string str = null;
for(int i=65; i

The idea behind the code above is to display all alphabetical characters from A to Z. However, there is an issue in the first statement. When you assign null to a string object and then attempt to add a string to it, the compiler will issue an error: “Cannot convert null literal to non-nullable reference or unconstrained type parameter.” This is because, beginning with C# 8, all reference types are non-nullable by default.

Figure 3 shows how GitHub Copilot fixes the code for you.

GitHub Copilot bug fix

Figure 3

Foundry

Optimize your code using GitHub Copilot

Consider the following piece of code that shows two classes, Customer and DataManager. While Customer is just another POCO class (plain old CLR object), DataManager creates an instance of the Customer class using a method called Create that accepts the customer details (i.e., values for all properties of the class) as parameters.

class Customer
{
    public Guid Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address { get; set; }
    public string Email { get; set; }
}
class DataManager
{
    public Customer Create(Guid Id, string firstName, string lastName, string address, string email)
    {
        Customer customer = new Customer
        {
            Id = Guid.NewGuid(),
            FirstName = firstName,
            LastName = lastName,
            Address = address,
            Email = email
        };
        return customer;
    }
}

To optimize your code using GitHub Copilot, you can select the block of source code in the code editor, right-click and then click on “Ask Copilot”, and type “Optimize” in the input box, as shown in Figure 4.

GitHub Copilot optimize code

Figure 4

Foundry

When you click on the arrow button beside the input box to submit the “Optimize” prompt to Copilot, it will generate the optimized code as shown in Figure 5.

GitHub Copilot optimize code results

Figure 5

Foundry

Create unit tests using GitHub Copilot

Testing is key to reliable software, and GitHub Copilot makes software testing faster and easier. You can use GitHub Copilot to generate boilerplate test code for your functions or classes based on the logic it detects. Moreover, Copilot can provide you with suggestions for unit test cases across different scenarios, including edge cases. Copilot can also help create mocks or stubs for dependencies so that you can get to testing faster.

To generate unit tests with GitHub Copilot, right-click in the code editor inside Visual Studio and click “Ask Copilot”. In the input box, simply enter an instruction such as “Write unit tests for all methods of the DataManager class” as shown in Figure 6 below.

GitHub Copilot unit tests

Figure 6

Foundry

When you click on the arrow button in the input box, Copilot will create a new file in your project named DataManagerTests.cs and generate unit tests for the DataManager class as shown in Figure 7.

GitHub Copilot unit tests results

Figure 7

Foundry

Thus you can see how GitHub Copilot helps you reduce the time you spend writing boilerplate test code and helps you be more productive with test cases.

Key takeaways

By accelerating the coding process, fixing bugs, and writing tests, GitHub Copilot lets you focus on what really matters: building great software. Whether you’re building enterprise-scale distributed systems or rapid-prototyping new ideas, you should try GitHub Copilot and see how it can improve your software development workflow.

I’ll explore more GitHub Copilot capabilities, such as how Copilot can generate integration tests and improve test coverage, in future posts here.

(image/jpeg; 5.11 MB)

For agentic AI, other disciplines need their own Git 15 Jan 2026, 9:00 am

Software engineering didn’t adopt AI agents faster because engineers are more adventurous, or the use case was better. They adopted them more quickly because they already had Git.

Long before AI arrived, software development had normalized version control, branching, structured approvals, reproducibility, and diff-based accountability. These weren’t conveniences. They were the infrastructure that made collaboration possible. When AI agents appeared, they fit naturally into a discipline that already knew how to absorb change without losing control.

Other disciplines now want similar leverage from AI agents. But they are discovering an uncomfortable truth: without a Git-equivalent backbone, AI doesn’t compound. It destabilizes.

What these disciplines need is not a literal code repository, but a shared operational substrate: a canonical artifact, fine-grained versioning, structured workflows, and an agreed-upon way to propose, review, approve, and audit changes.

Consider a simple example. Imagine a product marketing team using an AI agent to maintain competitive intelligence. The agent gathers information, synthesizes insights, and updates a master brief used by sales and leadership. This seems straightforward—until the agent edits the document.

In software, Git handles this effortlessly. Every change has a branch. Every branch produces a diff. Every diff is reviewed. Every merge is recorded. Every version is reproducible. Agents can propose changes safely because the workflow itself enforces isolation and accountability.

Life without version control

For the marketing team, no such backbone exists. If the agent overwrites a paragraph, where is the diff? If it introduces a factual error, where is the audit trail? If leadership wants to revert to last week’s version, what does that even mean? The lack of structure turns AI agents into risks.

This is why Git matters. Not because it is clever, but because it enforces process discipline: explicit change control, durable history, isolated work, and reproducibility. It created a shared contract for collaboration that made modern software engineering possible, and made agentic workflows in software engineering viable.

Other disciplines need structures that mirror these properties.

Take architecture or urban planning. Teams want AI agents to update simulations, explore zoning scenarios, or annotate design models. But without a versioning protocol for spatial artifacts, changes become opaque. An agent that modifies a zoning scenario without a traceable change set is effectively unreviewable.

Or consider finance. Analysts want agents to maintain models, update assumptions, and draft memos. Yet many organizations lack a unified way to version models, track dependencies, and require approvals. Without that substrate, automation introduces new failure modes instead of leverage.

At this point, the Git analogy feels strong—but it has limits.

Software is unusually forgiving of mistakes. A bad commit can be reverted. A merge can be blocked. Even a production outage usually leaves behind logs and artifacts. Version management works in part because the world it governs is reversible.

Many other disciplines are not.

Pulling irreversible levers

Consider HR. Imagine an organization asking an AI agent to terminate a vendor contract with “Joe’s Plumbing.” The agent misinterprets the context and instead terminates the employment of a human employee named Joe Plummer. There is no pull request. No staging environment. No clean revert. Payroll is cut, access is revoked, and legal exposure begins immediately. Even if the error is caught minutes later, the damage is already real.

This is the critical distinction. In non-code domains, actions often escape the system boundary. They trigger emails, revoke credentials, initiate payments, or change legal status. Version history can explain what happened, but it cannot undo it.

This means a Git-style model is necessary, but insufficient.

Applying diffs, approvals, and history without respecting execution boundaries creates a false sense of safety. In these domains, agents must be constrained not just by review workflows, but by strict separation between proposal and execution. Agents should prepare actions, simulate outcomes, and surface intent—without directly pulling irreversible levers.

Several patterns from software translate cleanly: durable history creates accountability; branching protects the canonical state; structured approvals are the primary mechanism of resilience; reproducibility enables auditing and learning.

Disciplines that lack these properties will struggle to govern AI agents. Tools alone won’t fix this. They need norms, repeatable processes, and artifact structure—in short, their own Git, adapted to their risk profile.

The lesson from software is not that AI adoption is easy. It is that adoption is procedural before it is technical. Git quietly orchestrates isolation, clarity, history, and review. Every discipline that wants similar gains will need an equivalent backbone—and, where mistakes are irreversible, a way to keep the genie in the bottle.

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.

(image/jpeg; 11.55 MB)

What is GitOps? Extending devops to Kubernetes and beyond 15 Jan 2026, 9:00 am

Over the past decade, software development has been shaped by two closely related transformations. One is the rise of devops and continuous integration and continuous delivery (CI/CD), which brought development and operations teams together around automated, incremental software delivery.

The other is the shift from monolithic applications to distributed, cloud-native systems built from microservices and containers, typically managed by orchestration platforms such as Kubernetes.

While Kubernetes and similar platforms simplify many aspects of running distributed applications, operating these systems at scale is still complicated. Configuration sprawl, environment drift, and the need for rapid, reliable change all introduce operational challenges. GitOps emerged as a way to address those challenges by extending familiar devops and CI/CD techniques beyond application code and into infrastructure and system configuration.

At the heart of GitOps is the concept of infrastructure as code (IaC). In a GitOps model, not only application code but also infrastructure definitions, deployment configurations, and operational settings are described in files stored in a version control system. Automated processes continuously compare the running system with those declarations and work to bring the live environment back into alignment when differences appear.

In this approach, the version control repository serves as the system of record for how applications and their supporting infrastructure should look in production. Changes flow through the same review, approval, and automation pipelines that developers already use for software, bringing greater consistency, traceability, and repeatability to cloud-native operations.

At a high level, GitOps refers to a set of operational practices for managing cloud-native systems using declarative configuration, version control, and automated reconciliation. Rather than treating infrastructure and application configuration as mutable runtime state, GitOps treats them as versioned artifacts that move through the same review, testing, and deployment processes as application code.

GitOps defined

The term GitOps was originally coined and popularized by Weaveworks, which helped formalize the approach in the context of Kubernetes operations. While that early work shaped the way GitOps was discussed and implemented, GitOps has since evolved into a broadly adopted, vendor-neutral pattern. Today, it describes a shared set of ideas rather than a specific product or platform.

The defining characteristic of GitOps is its reliance on declarative configuration stored in a version control system. Instead of issuing imperative commands to change live systems, teams describe the desired state of applications and infrastructure in configuration files. Automated agents then continuously compare that declared state with what is actually running and work to reconcile any differences. This pull-based model—where systems converge toward the desired state defined in version control—provides built-in drift detection, repeatability, and a clear audit trail for every change.

Because GitOps centers on configuration files stored in a version control system, familiar software development practices carry over naturally. Changes are proposed through commits, reviewed before being accepted, and tracked over time. Rollbacks are accomplished by reverting to known-good versions, and the history of how a system evolved is preserved alongside the configuration itself.

While the use of Git as the version control system is not strictly required, it has become the default choice because of its ubiquity in modern devops workflows and its strong support for collaboration and change management, so its place in the name has stuck.

What is the CI/CD process?

A complete look at CI/CD is beyond the scope of this article—see the InfoWorld explainer on the subject—but we need to say a few words about CI/CD because it’s at the core of how GitOps works. The continuous integration half of CI/CD is enabled by version control repositories like Git: Developers can make constant small improvements to their codebase, rather than rolling out huge, monolithic new versions every few months or years. The continuous deployment piece is made possible by automated systems called pipelines that build, test, and deploy the new code to production.

Again, we keep talking about code here, and that usually summons up visions of executable code written in a programming language such as C or Java or JavaScript. But in GitOps, the “code” we’re managing is largely made up of configuration files. This isn’t just a minor detail — it’s at the heart of what GitOps does. These config files are, as we’ve said, the “single source of truth” describing what our system should look like. They are declarative rather than instructive. That means that instead of saying “start up ten servers,” the configuration file will simply say, “this system includes ten servers.”

GitOps and Kubernetes

GitOps first took hold in the Kubernetes ecosystem, where declarative configuration and continuous reconciliation are core design principles. As a result, Kubernetes remains the most common and best-understood environment for applying GitOps practices. A typical GitOps-driven update process for a Kubernetes application looks like this:

  1. A developer proposes a change by committing updated application code or configuration to a version control repository, usually through a pull request.
  2. That change is reviewed and approved, then merged into the main branch.
  3. The merge triggers an automated CI/CD pipeline that tests the change, builds new artifacts if needed, and publishes them to a registry.
  4. A GitOps controller or similar automated agent detects the updated desired state stored in version control.
  5. The controller compares that desired state with the current state of the Kubernetes cluster and applies the necessary changes to bring the cluster back into alignment.

This pull-based reconciliation loop—where the cluster continuously converges toward the desired state defined in version control—is central to how GitOps works in practice. While Kubernetes provides a natural fit for this model, it represents just one canonical use case. The same patterns increasingly apply to infrastructure provisioning, policy enforcement, and multi-cluster operations beyond Kubernetes itself.

GitOps tooling in practice: Argo CD, Flux, and the ecosystem

GitOps is enabled by a set of tools that embody the principles we’ve outlined, with some open-source projects emerging as de facto standards in cloud-native environments.

At the center of the GitOps ecosystem is Argo CD, an open-source controller that continuously monitors a version control repository and ensures that the state of running systems matches the declared desired state. Argo CD is widely used in Kubernetes environments because it directly implements pull-based reconciliation: it compares the desired state stored in Git with the cluster’s actual state and applies changes to correct any drift.

Alongside Argo CD, Flux is another prominent open source GitOps engine. Both Flux and Argo CD help teams adopt GitOps workflows by managing the synchronization loop between code and runtime, but they differ in operational philosophy, integration surfaces, and ecosystem fit.

GitOps tooling often appears as part of broader platforms or integrated stacks rather than as isolated utilities. For example, multicloud and cluster management solutions now routinely include GitOps support, with Argo CD or compatible controllers bundled alongside deployment, policy, and governance capabilities.

In addition to Flux and Argo CD, a range of auxiliary tools contribute to a complete GitOps ecosystem: policy as code engines (e.g., Open Policy Agent), drift detection systems, and infrastructure provisioning tools that mesh with Git-centric workflows.

GitOps, devops, and normalization

GitOps grew out of the same forces that drove devops into mainstream IT practice, and in its early days, GitOps was often discussed as a distinct extension of devops, specifically tailored to managing declarative infrastructure and Kubernetes-centric systems. At the time, GitOps was still relatively new and not yet widely adopted outside cloud-native pioneers.

Over the last several years, however, GitOps practices have become deeply woven into how teams operate modern cloud environments. Rather than being treated as an optional add-on or marketing term, the core ideas of GitOps — using version-controlled, declarative configuration and automated reconciliation loops to continuously align running systems with intended state — are now part of standard operational practice in many Kubernetes-centric shops. In this sense, GitOps has shifted from a buzzword about what might be possible to a baseline pattern for cloud-native operations, much like devops itself did years earlier.

In environments where Kubernetes and declarative systems are the norm, GitOps workflows are the default way teams manage and deploy change. Many organizations now implement these patterns without explicitly calling them “GitOps,” just as few teams today explicitly say they do “CI/CD” even though continuous pipelines are taken for granted. The term has become less prominent in marketing, but its practices are often embedded in pipelines, controllers, and platform tooling.

That normalization shows up in how GitOps workflows are woven into broader operational frameworks. For example, platform engineering teams frequently build internal developer platforms that encapsulate GitOps patterns behind standardized developer APIs, making the pattern invisible to most application teams while still providing the auditability and automation that GitOps promises.

GitOps beyond Kubernetes: infrastructure, policy, and drift

While GitOps first gained traction as a way to manage Kubernetes deployments, its core principles apply broadly to infrastructure and operational concerns beyond any single orchestration platform. GitOps treats desired state as declarative configuration stored in version control and uses automated reconciliation to ensure running systems align with that state. That pattern naturally extends to infrastructure provisioning, policy enforcement, configuration drift detection, and governance workflows across diverse environments.

In modern operational stacks, infrastructure is increasingly defined declaratively, whether through Kubernetes manifests, Terraform modules, or other infrastructure-as-code formats. Storing these declarations in version control enables the same peer-review, auditability, and rollback practices developers already use for application code. Automated tooling then continuously detects when the live infrastructure diverges from the declared state and works to bring it back into alignment, reducing the risk of configuration drift and inadvertent misconfigurations.

Configuration drift — the state where an environment has diverged from what’s declared in version control — remains a major operational headache, especially in complex, dynamic systems. Drift can arise from ad hoc fixes, emergency updates, or manual changes made outside normal pipelines, and it can lead to inconsistencies, outages, and security gaps. By continually checking running systems against the desired state in Git and reconciling deviations automatically, GitOps workflows help teams keep environments predictable and auditable.

Policy enforcement and compliance are another natural extension of GitOps patterns. As organizations adopt declarative practices, policy-as-code engines and drift detection systems can be woven into GitOps pipelines to validate that proposed configurations meet security, compliance, or operational standards before they’re ever applied to running systems. Embedding policy checks into declarative workflows brings consistency to governance while preserving the automation and speed that devops teams expect.

GitOps – beyond Kubernetes

GitOps began as a way to bring devops discipline to Kubernetes operations, but its longer-term impact has been more subtle. In many ways, it’s been absorbed into the fabric of modern cloud-native operations, where declarative configuration, version control, and automated reconciliation are taken for granted. Today, GitOps is less about a specific set of tools or a named practice and more about an operational mindset. By treating infrastructure and configuration as versioned, auditable artifacts and relying on automation to enforce consistency, GitOps helps teams manage complexity at scale. Even as the term itself fades from the spotlight, the practices it introduced continue to shape how distributed systems are built, deployed, and operated.

(image/jpeg; 0.43 MB)

React tutorial: Get started with the React JavaScript library 15 Jan 2026, 9:00 am

Despite many worthy contenders, React remains the most popular front-end framework, and a key player in the JavaScript development landscape. React is the quintessential reactive engine, continually innovating alongside the rest of the industry. A flagship open source project at Facebook, React is now part of Meta Open Source. For developers new to JavaScript and web development, this tutorial will get you started with this vital technology.

React is not only a front-end framework, but is a component in full-stack frameworks like Next.js. Newer additions like React server-side rendering (SSR) and React server components (RSC) further blur the line between server and client.

Also see: Is the React compiler ready for primetime?

Why React?

React’s prominence makes it an obvious choice for developers just starting out with web development. It is often chosen for its ability to offer a smooth and encompassing developer experience (DX), which distinguishes it from frameworks like Vue, Angular, and Svelte. It could be said that React’s true “killer feature” is the perks that come with longstanding popularity: learning resources, community support, libraries, and developers are all plentiful in the React ecosystem.

Installing React

Real-world React requires running on the server with a build tool, which we will explore in the next section. But to get your feet wet, we can start out with an online playground. There are several high-quality playgrounds for React, including full-blown environments like StackBlitz or Codesandbox. For a quick taste, we will use PlayCode React.

When you first open it, PlayCode React gives you a basic layout like the one shown here:

A screenshot shows the layout of a basic Rwact JavaScript application.

Matthew Tyson

The menu on the left is the file explorer, at the top is the code window, and at the bottom are the console (on the left) and the preview pane (on the right).

From this screenshot, you can see how the content of the code is displayed on the preview pane, but this basic layout doesn’t use any variables (or “state,” as it’s known in React). It does let you see some of the plumbing, like the React library import and the exported App function.

Modern React is functional. The App function has a return value that is the actual output for the component. The component’s return is specified by JSX, a templating language that lets you use HTML along with variables and JavaScript expressions. Right now, the app just has some simple markup.

The classic example you see next is a “Counter” that lets you increase and decrease a displayed value using buttons. We’ll do a slight “Spinal Tap” variation of this, where the counter only goes to 11 and displays a message:

A screenshot of a counter app developed in React.

Matthew Tyson

You can take a look at the running example here, and the full code for the example is below:

import React, { useState } from 'react';

export function App() {
  // 1. The State
  const [volume, setVolume] = useState(0);

  return (
    

Spinal Tap Amp 🎸

{/* 2. The "View" (Displaying the state) */}
{volume}
{/* 3. The Actions */
{/* 4. Conditional */} {volume === 11 &&

"Why don't you just make ten louder?"

}
); }

If you play with the example, you’ll see that moving the buttons changes the value, and the display automatically reflects the change. This is the essential magic of a reactive engine like React. The state is a managed variable that React automatically updates and displays. State is declared like so:

const [volume, setVolume] = useState(0);

The syntax is a bit funky if you are coming from straight JavaScript, but most developers can adapt to it quickly. Basically, useState(0) says, with a default value 0, give me a variable, volume, and a function to set it, setVolume.

To display the value in the view, we use: {volume}.

To modify the value, we use button event handlers. For example, to increment, we’d do:

To modify the value, we use buttons event handlers.  For example, to increment:

onClick={() => setVolume(volume + 1)

Here we’ve directly modified the volume state, and React will update accordingly. If we wanted to, we could call a function (for example, if the logic were more involved).

Finally, when the value reaches 11, we display a message. This syntax is idiomatic React, and uses an embedded JavaScript equality check:

{volume === 11 &&
  

"Why don't you just make ten louder?"

}

The check says, if volume is 11, then display the

markup.

Using a build tool with React

Once upon a time, when NVIDIA was nothing but a graphics card, it was quite a bit of work assembling a good build chain for React. These days, the process is much simpler, and the once ubiquitous create-react-app option is no more. Vite is now the standard choice for launching a new app from the React terminal, so that’s the approach you’ll learn here.

With that said, there are a few alternatives worth mentioning. VS Code has extensions that will provide you with templates or scaffolding, but what’s becoming more common is using an AI coding assistant. A tool like Copilot, ChatGPT, or Gemini can take a prompt describing the basics of the application in question, including the instruction to use React, and produce a basic React layout for you. AI assistants are available in both command-line and VS Code extension flavors. Or, for an even more forward-looking option, you could use something like Firebase Studio.

But enough about alternatives—Vite is the standard for a reason. It is repeatable, capable, and fast. To launch a new Vite app, you just enter the following in your command line:

$ npm create vite@latest

The interactive tool will walk you through the process, starting with selecting React as your technology:

A screenshot of the Vite CLI showing the option to select React.

Matthew Tyson

Use your own preferences for the other options (like using TypeScript versus JavaScript) and accept the option to install and launch the app immediately. Afterward, you’ll see a simple demo like this one:

A screenshot showing the Vite demo app built with React.

Matthew Tyson

The demo app has a counter component like the one we built earlier. If you Ctrl-c (or Cmd-c) to kill the Vite process running in the terminal, you can cd into the new directory. From there, you can see where the counter component is defined, in src/App.jsx (or App.tsx if you have selected TypeScript like I have).

It’s worth looking at that file to see how React appears on the server:

src/App.tsx
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'

function App() {
  const [count, setCount] = useState(0)

  return (
    
      
      

Vite + React

Edit src/App.tsx and save to test HMR

Click on the Vite and React logos to learn more

> ) } export default App

Notice we export the App as a module, which is used by the src/main.tsx file to display the component in the view. That file creates the bridge between the respective worlds of React and HTML:

import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'

createRoot(document.getElementById('root')!).render(
  
    
  ,
)

Don’t worry too much about the details of how React bootstraps itself with createRoot and the render call (which you won’t have to interact with on a regular basis). The important thing is how the App component is imported and then used with the JSX.

Note

Strict mode adds warning during dev mode to help you catch component bugs early.

There are a few rules to bear in mind when using JSX, the templating language of React:

  • HTML elements are lowercase (
    , ), but components are uppercase (, ).
  • You can’t just type “class” in JSX; instead, use className; e.g.,
    .
  • To access the realm of JavaScript (and the application state) from within JSX, use curly braces: {2 + 2 != 5}.
  • React components and props

    The main organizational concept in React is the component. Components are used to contain the functionality for a part of the view within a self-contained package. We’ve seen a component in action already with but it might be a little obscure, so let’s add another simple component to enhance the demonstration. This component also lets us explore another key part of React: Props.

    To start, let’s create a display of the counter value influenced by the Rob Reiner movie This Is Spinal Tap. To start, we create a new file at src/VolumeDisplay.jsx:

    // src/VolumeDisplay.jsx
    
    export function VolumeDisplay({ level }) {
      return (
        
    {/* The Dial */}
    = 11 ? '#d32f2f' : '#f0f0f0', color: level >= 11 ? 'white' : 'black', transition: 'all 0.2s ease' }}> {level}
    {/* The Message */} {level >= 11 && (

    "These go to eleven." 🤘

    )}
    ); }

    This is a simple display but there are a couple of things worth noting about it.

    One is that we accept a prop (a property) “from above” with VolumeDisplay({ level }). This tells whatever parent component uses this one that VolumeDisplay accepts a single property, called level. VolumeDisplay uses the property by displaying it (though it adds a bit of fancying up using conditional logic like we have already seen).

    The way we define the CSS values, inside the double braces, {{ }}, and as a map of value is idiomatic React. (It isn’t essential at this point to grasp why it works that way, but basically, it is the JSX token { } with a JavaScript map of CSS values using JavaScript-friendly camel-cased names, like justifyContent.)

    Now, to utilize this component, we can go to App.jsx, and make two changes:

    import { useState } from 'react'
    import reactLogo from './assets/react.svg'
    import viteLogo from '/vite.svg'
    import './App.css'
    // 1. Import our new component
    import { VolumeDisplay } from './VolumeDisplay'
    
    function App() {
      const [count, setCount] = useState(0)
    
      return (
        
          
          

    Vite + React

    {/* 2. Pass the 'count' state into the 'level' prop */}

    Edit src/App.tsx and save to test HMR

    Click on the Vite and React logos to learn more

    > ) } export default App

    Here, we’ve done two things: imported the new component and used it in the view.

    Notice, also, that the line passes the existing count state variable into VolumeDisplay as a prop. React will do the work of ensuring that whenever count changes, the VolumeDisplay will also be updated, including any dependent logic such as the conditional statements.

    Now, if we run the code like so:

    $ npm run dev

    We get what you see in the screenshot below:

    A screenshot of the running demo app built with Vite and React.

    Matthew Tyson

    Conclusion

    The world is now your oyster, at least within the realm of JavaScript web development. Not only is React wildly popular, its basic ideas are applicable to a host of other innovative frameworks, including Svelte and Solid. (To get some idea of the alternatives, just type npm create vite@latest and look at all the available technologies.) Now that you have a basic introduction, a good next step for learning would be to add an control that allows typing in the volume manually. Happy coding!

(image/jpeg; 11.59 MB)

From typos to takeovers: Inside the industrialization of npm supply chain attacks 15 Jan 2026, 7:48 am

A massive surge in attacks on the npm ecosystem over the past year reveals a stark shift in the software supply‑chain threat landscape.

What once amounted to sloppy typosquatting attempts has evolved into coordinated, credential-driven intrusions targeting maintainers, CI pipelines, and the trusted automation that underpins modern development.

For security leaders, these aren’t niche developer mishaps anymore — they’re a direct pathway into production systems, cloud infrastructure, and millions of downstream applications.

The goal is no longer to trick an individual developer, but to quietly inherit their authority. And with it, their distribution reach.

“NPM is an attractive target because it is the world’s largest JavaScript package repository and a key control point for distributing software,” said Melinda Marks, cybersecurity practice director at Enterprise Security Group. “Security teams need an understanding of dependencies and ways to regularly audit and mitigate risk.”

Structural weaknesses in the npm infrastructure

Nearly every enterprise relies on npm, whether directly or indirectly. According to IDC, 93% of organizations use open-source software, and npm remains the largest package registry in the JavaScript ecosystem. “Compromising a single popular package can immediately reach millions of downstream users and applications,” IDC’s research manager (DevSecOps), Katie Norton, said, turning one stolen credential into what she described as a “master key” for distribution.

That scale, however, is only part of the risk.

The exposure is amplified by structural weaknesses in how modern development pipelines are secured, Norton remarked. “Individual open-source maintainers often lack the security resources that enterprise teams rely on, leaving them susceptible to social engineering,” she said. “CI/CD runners and developer machines routinely process long-lived secrets that are stored in environment variables or configuration files and are easily harvested by malware.”

“Build systems also tend to prioritize speed and reliability over security visibility, resulting in limited monitoring and long dwell times for attackers who gain initial access,” Norton added.

While security leaders can’t patch their way out of this one, they can reduce exposure. Experts consistently point to the same priorities: treating CI runners as production assets, rotating and scoping publish tokens aggressively, disabling lifecycle scripts unless required, and pinning dependencies to immutable versions.

“These npm attacks are targeting the pre-install phase of software dependencies, so typical software supply chain security methods of code scanning cannot address these types of attacks,” Marks said. Detection requires runtime analysis and anomaly detection rather than signature-based tooling.

From typo traps to legitimate backdoors

For years, typosquatting defined the npm threat model. Attackers published packages with names just close enough to popular libraries, such as “lodsash,” “expres,” “reacts,” and waited for automation or human error to do the rest. The impact was usually limited, and remediation straightforward.

That model began to break in 2025.

Instead of impersonating popular packages, attackers increasingly compromised real ones. Phishing campaigns spoofing npm itself harvested maintainer credentials. Stolen tokens were then used to publish trojanized updates that appeared legitimate to every downstream consumer. The Shai-Hulud campaign illustrated the scale of the problem, affecting tens of thousands of repositories and leveraging compromised credentials to self-propagate across the ecosystem.

“The npm ecosystem has become the crown jewels of modern development,” said Kush Pandya, a cybersecurity researcher at Socket.dev. “When a single prolific maintainer is compromised, the blast radius spans hundreds of downstream projects.”

The result was a quiet but powerful shift: attackers no longer needed to create convincing fakes. They could ship malware through trusted channels, signed and versioned like any routine update.

Developer environments over developer laptops

Modern npm attacks increasingly activate inside CI/CD environments rather than on developer laptops. Post-install scripts, long treated as benign setup helpers, became an execution vector capable of running automatically inside GitHub Actions or GitLab CI. Once inside a runner, malicious packages could read environment variables, steal publish tokens, tamper with build artifacts, or even push additional malicious releases under the victim’s identity.

“Developer environments and CI runners are now worth more than end-user machines,” Pandya noted. “They usually have broader permissions, access to secrets, and the ability to push code into production.”

Several campaigns observed in mid-2025 were explicitly CI-aware, triggering only when they detected automated build environments. Some included delayed execution or self-expiring payloads, minimizing forensic visibility while maximizing credential theft.

For enterprises, this represents a fundamental risk shift. CI systems often operate with higher privileges than any individual user, yet are monitored far less rigorously. “They are often secured with weaker defaults: long-lived publish tokens, overly permissive CI secrets, implicit trust in lifecycle scripts and package metadata, and little isolation between builds,” Pandya noted.

According to IDC Research, organizations allocate only about 14% of AppSec budgets to supply-chain security, with only 12% of them identifying CI/CD pipeline security as a top risk.

Evasion as a first-class feature

As defenders improved at spotting suspicious packages, attackers adapted too.

Recent npm campaigns have used invisible Unicode characters to obscure dependencies, multi-stage loaders that fetch real payloads only after environment checks, and blockchain-hosted command-and-control (C2) references designed to evade takedowns. Others deployed worm-like behavior, using stolen credentials to publish additional malicious packages at scale.

Manual review has become largely ineffective against this level of tradecraft. “The days when you could skim index.js and spot a malicious eval() are gone,” Pandya said.

“Modern packages hide malicious logic behind layers of encoding, delayed execution, and environment fingerprinting.” Norton echoed the concern, noting that these attacks operate at a behavioral level where static scanning falls short. “Obfuscation techniques make malicious logic difficult to distinguish from legitimate complexity in large JavaScript projects,” she said. “CI-aware payloads and post-install scripts introduce behavior that only manifests under specific environmental conditions.”

(image/jpeg; 5.22 MB)

Compose Multiplatform brings auto-resizing to interop views 14 Jan 2026, 11:24 pm

JetBrains has released Compose Multiplatform 1.10.0, the latest version of the Kotlin-based declarative framework for building shared UIs across multiple platforms. Unveiled January 13, the update supports automatic resizing for native interop elements on both desktop and iOS deployments.

Resizing of these elements means they now can adapt their layout to their content, eliminating the need to calculate exact sizes manually and specify fixed dimensions in advance. On the desktop,SwingPaneladjusts its size based on the embedded component’s minimum, preferred, and maximum sizes. For iOS, UIKit interop views now support sizing according to the view’s fitting size (intrinsic content size). This enables proper wrapping of SwiftUI views (via UIHostingController) and basic UIView subclasses that do not depend on NSLayoutConstraints.

Instructions on getting started with Compose Multiplatform can be found at kotlang.org. Compose Multiplatform is an optional UI framework built atop Kotlin Multiplatform technology, for building applications for different platforms and reusing code. Compose Multiplatform applications will run on iOS, Android, macOS, Windows, Linux, and the web.

Also in version 1.10.0, Compose Multiplatform now uses the Web Cache API to cache successful responses for static assets and string resources. This avoids the delays associated with the browser’s default cache, which validates stored content through repeated HTTP requests and can be slow on low-bandwidth connections. The cache is cleared on every app launch or page refresh to ensure resources remain consistent with the application’s current state. This capability is an experimental feature.

Other improvements in Compose Multiplatform 1.10.0 include:

  • The Compose Hot Reload plugin now is bundled with the Compose Multiplatform Gradle plugin. Users no longer need to configure the Hot Reload plugin separately, as it is enabled by default for Compose Multiplatform projects targeting desktop.
  • The approach to previews has been unified across platforms. Developers can now use the androidx.compose.ui.tooling.preview.Preview annotation in thecommonMainsource set. Other annotations, such as org.jetbrains.compose.ui.tooling.preview.Previewand the desktop-specific androidx.compose.desktop.ui.tooling.preview.Preview, have been deprecated.
  • Navigation 3, a new library for managing navigation, is now supported on non-Android targets.
  • The following properties inDialogPropertieshave been promoted to stable and are no longer experimental: usePlatformInsets, useSoftwareKeyboardInset, and scrimColor. Similarly, the usePlatformDefaultWidth and usePlatformInsetsproperties in PopupProperties have also been promoted to stable.
  • The deprecation level for Popup overloads without the PopupProperties parameter has been changed to ERROR to enforce the use of the updated API.
  • For iOS, Compose Multiplatform now supports WindowInsetsRulers, which provides functionality to position and size UI elements based on window insets, such as the status bar, navigation bar, or on-screen keyboard.

(image/jpeg; 4.48 MB)

Output from vibe coding tools prone to critical security flaws, study finds 14 Jan 2026, 8:08 pm

Popular vibe coding platforms consistently generate insecure code in response to common programming prompts, including creating vulnerabilities rated as ‘critical,’ new testing has found.

Security startup Tenzai’s top-line conclusion: the tools are good at avoiding security flaws that can be solved in a generic way, but struggle where what distinguishes safe from dangerous depends on context.

The assessment, which it conducted in December 2025, compared five of the best-known vibe coding tools — Claude Code, OpenAI Codex, Cursor, Replit, and Devin — by using pre-defined prompts to build the same three test applications.

In total, the code output by the five tools across 15 applications (three each) was found to contain a total of 69 vulnerabilities. Around 45 of these were rated ‘low-medium’ in severity, with many of the remainder rated ‘high’ and around half a dozen ‘critical’.

While the number of low-medium vulnerabilities was the same for all five tools, only Claude Code (4 flaws), Devin (1) and Codex (1) generated critical-rated vulnerabilities.

The most serious vulnerabilities concerned API authorization logic (checking who is allowed to access a resource or perform an action), and business logic (permitting a user action that shouldn’t be possible), both important for e-commerce systems.

“[Code generated by AI] agents seems to be very prone to business logic vulnerabilities. While human developers bring intuitive understanding that helps them grasp how workflows should operate, agents lack this ‘common sense’ and depend mainly on explicit instructions,” said Tenzai’s researchers.

Offsetting this, the tools did a good job of avoiding common flaws that have long plagued human-coded applications, such as SQLi or XSS vulnerabilities that are both still prominently featured in the OWASP Top 10 list of web application security risks.

“Across all the applications we developed, we didn’t encounter a single exploitable SQLi or XSS vulnerability,” said Tenzai.

Human oversight

The vibe coding sales pitch is that it automates everyday programming jobs, boosting productivity. While this is undoubtedly true, Tenzai’s test shows that the idea has limits; human oversight and debugging are still needed.

This isn’t a new discovery. In the year since the concept of ‘vibe coding’ was developed, other studies have found that, without proper supervision, these tools are prone to introducing new cyber security weaknesses.

But it’s not simply that vibe coding platforms aren’t picking up security flaws in their code; in some cases, defining what counts as good or bad is simply impossible using general rules or examples.

“Take SSRF [Server-Side Request Forgery]: there’s no universal rule for distinguishing legitimate URL fetches from malicious ones. The line between safe and dangerous depends heavily on context, making generic solutions impossible,” said Tenzai. 

The obvious solution is that, having invented vibe coding agents, the industry should now focus on vibe coding checking agents, which, of course, is where Tenzai, a small startup not long out of stealth mode, thinks it has found a gap in the market for its own technology. It said, “based on our testing and recent research, no comprehensive solution to this issue currently exists. This makes it critical for developers to understand the common pitfalls of coding agents and prepare accordingly.”

Debugging AI

The deeper question raised by vibe coding isn’t how well tools work, then, but how they are used. Telling developers to keep eyes on vibe code output isn’t the same as knowing this will happen, any more than it was in the days when humans made all the mistakes.

“When implementing vibe coding approaches, companies should ensure that secure code review is part of any Secure Software Development Lifecycle and is consistently implemented,” commented Matthew Robbins, head of offensive security at security services company Talion. “Good practice frameworks should also be leveraged, such as the language-agnostic OWASP Secure Coding Practices, and language-specific frameworks such as SEI CERT coding standards.” 

Code should be tested using static and dynamic analysis before being deployed, Robbins added. The trick is to get debugging right. “Although vibe coding presents a risk, it can be managed by closely adhering to industry-standard processes and guidelines that go further than traditional debugging and quality assurance,” he noted.

However, according to Eran Kinsbruner, VP of product marketing at application testing organization Checkmarx, traditional debugging risks being overwhelmed by the AI era.

“Mandating more debugging is the wrong instinct for an AI-speed problem. Debugging assumes humans can meaningfully review AI-generated code after the fact. At the scale and velocity of vibe coding, that assumption collapses,” he said.

“The only viable response is to move security into the act of creation. In practice, this means agentic security must become a native companion to AI coding assistants, embedded directly inside AI-first development environments, not bolted on downstream.”

This article originally appeared on CSOonline.

(image/jpeg; 0.29 MB)

Chinese AI firm trains state-of-the-art model entirely on Huawei chips 14 Jan 2026, 3:04 pm

Chinese company Zhipu AI has trained image generation model entirely on Huawei processors, demonstrating that Chinese firms can build competitive AI systems without access to advanced Western chips.

The model, released on Tuesday, marks the first time a state-of-the-art multimodal model completed its full training cycle on Chinese-made chips, Zhipu said in a statement. The Beijing-based company trained the model on Huawei’s Ascend Atlas 800T A2 devices using the MindSpore AI framework, completing the entire pipeline from data preprocessing through large-scale training without relying on Western hardware.

The achievement carries strategic significance for Zhipu, which the US Commerce Department last year added to a list of entities acting contrary to US national security or foreign policy interests over its alleged ties to China’s military. The designation effectively cut the company off from Nvidia’s H100 and A100 GPUs, which have become standard for training advanced AI models, forcing Chinese firms to develop alternatives around domestic chip architectures.

Followign that listing, Zhipu began collaborating with Huawei on GLM-Image. Huawei’s Ascend processors have become the primary alternative for Chinese AI companies restricted from purchasing Nvidia’s hardware. The model’s successful training on Ascend chips provides a data point that Chinese firms can develop competitive AI systems despite restricted access to Western chips.

“This proves the feasibility of training high-performance multimodal generative models on a domestically developed full-stack computing platform,” Zhipu’s statement added.

Zhipu has made GLM-Image available through an API for 0.1 yuan (approximately $0.014) per generated image. The company released the model weights on GitHub, Hugging Face, and ModelScope Community for independent deployment.

The pricing positions GLM-Image as a cost-effective option for enterprises generating marketing materials, presentations, and other text-heavy visual content at scale.

Technical approach and benchmark performance

GLM-Image employs a hybrid architecture combining a 9-billion-parameter autoregressive model with a 7-billion-parameter diffusion decoder, according to Zhipu’s technical report. The autoregressive component handles instruction understanding and overall image composition, while the diffusion decoder focuses on rendering fine details and accurate text.

The architecture addresses challenges in generating knowledge-intensive visual content where both semantic understanding and precise text rendering matter, such as presentation slides, infographics, and commercial posters.

On the CVTG-2K benchmark, which measures accuracy in placing text across multiple image locations, GLM-Image achieved a Word Accuracy score of 0.9116, ranking first among open-source models. The model also led the LongText-Bench test for rendering extended text passages, scoring 0.952 for English and 0.979 for Chinese across eight scenarios including signs, posters, and dialog boxes.

The model natively supports multiple resolutions from 1024×1024 to 2048×2048 pixels without requiring retraining, the report added.

Hardware optimization strategy

Training GLM-Image on Ascend hardware required Zhipu to develop custom optimization techniques for Huawei’s chip architecture. The company built a training suite that implements dynamic graph multi-level pipelined deployment, enabling different stages of the training process to run concurrently and reducing bottlenecks.

Zhipu also created high-performance fusion operators compatible with Ascend’s architecture and employed multi-stream parallelism to overlap communication and computation operations during distributed training. These optimizations aim to extract maximum performance from hardware that operates differently from the Nvidia GPUs most AI frameworks target by default.

The technical approach validates that competitive AI models can be trained on China’s domestic chip ecosystem, though at what cost in development time and engineering effort remains unclear.

Zhipu did not say how many processors or how long it took to train its model, nor how the requirements compared to equivalent Nvidia-based systems.

Implications for global AI development

For multinational enterprises operating in China, GLM-Image’s training on domestic hardware provides evidence that Chinese AI infrastructure can support state-of-the-art model development. Companies with Chinese operations may need to evaluate whether to develop strategies around platforms like Huawei’s Ascend and frameworks like MindSpore.

The release comes as Chinese companies invest in domestic AI infrastructure alternatives. Whether export controls will slow or accelerate the development of parallel AI ecosystems remains a subject of policy debate.

(image/jpeg; 2.66 MB)

When writing code is no longer the bottleneck 14 Jan 2026, 9:00 am

Last week it was looms. This week it is potato chips.

I’m a huge fan of EconTalk, a podcast hosted by Russ Roberts. Russ is a great guy and his guests are invariably interesting. One of my all-time favorite episodes is Brendan O’Donohoe on Potato Chips and Salty Snacks, in which O’Donohoe and Roberts talk about how potato chips are made. Now that might not sound interesting, but I found it fascinating. First, O’Donohoe is both an expert and an enthusiast about potato chips. (Who isn’t?) More interestingly, he provides valuable insights into how the process has become increasingly efficient over time. 

The main thrust of improving the production of potato chips was discovering the bottleneck and then fixing that step in the process until it was no longer the bottleneck. Once that bottleneck was removed, something else was found to be the bottleneck. Then you’d fix that, and so on, until the process is so efficient that it isn’t worth taking the time to fix the bottleneck that is barely a bottleneck at all anymore.

After I wrote the loom article last week, it occurred to me that the process of software development is no different. And thus, to improve it, we should find the bottleneck, figure out a way to make it no longer the bottleneck, and repeat. 

And it seems obvious to me that the actual coding of the application is the narrow, high-pressure point in the software development pipeline. In a process full of friction, writing the code is usually the bottleneck that determines when a project gets finished.

So what happens if writing code ceases to be the bottleneck? Well, I think we are just about there with agentic coding, no? For the sake of argument, and to keep this column rolling, let’s assume that such is the case. Let’s take it as granted that writing code becomes something that happens over days and weeks, and not weeks, months, or even years. 

What would that mean?

Well, first of all, requirements would have to become more specific. Right now, developers tend to accept requirements that are more vague than they might like because they know that things can be continuously refined and that we can “figure that all out as we go.” That won’t work with coding agents.

If an agentic coding system is fed vague inputs, it will produce vague outputs, right? Garbage in, garbage out is as true a statement as there is in computing. Thus, what you tell your coding agent to do will have to be clear and specific. Getting that right will be the new skill that software development teams have to develop. You might even view it as “coding in English.”

The next result is that a lot more software will be created, some of it good, some of it bad. Right now, I suspect there are many ideas for software—both features for existing software and whole new applications—that aren’t being built because the actual writing of the code is too costly or too difficult for the folks with the ideas. 

Sure, this is going to lead to a lot more “AI slop” software—easy execution always amplifies bad judgment—but there will also be a lot more great ideas that actually come to fruition. Existing software will end up with a lot more features than human developers alone could deliver. It will be the job of product managers to make sure that the product stays useful. (As a former product manager myself, I can say it would be great to be able to plow more quickly through a backlog of ideas.)

Developers will shift their focus from coding clean and well-organized implementations to making sure that the agents produce clean and well-organized implementations. Instead of writing most of the code, developers will spend their time reviewing, rejecting, constraining, and refactoring the agents’ output. Or better still, they will spend their time directing the agents to do that.

Ultimately, the next bottleneck will become proper thinking about what should be done. When you can do everything, deciding what not to do becomes the really difficult decision. Deciding what not to do is a problem today. Imagine how much harder it will be when, instead of choosing three things out of seven, product managers need to choose 30 things out of 70. 

(image/jpeg; 6.74 MB)

Rust slow to compile? Here’s how to speed it up 14 Jan 2026, 9:00 am

Developers choose Rust because they can use it to write software that is memory-safe, correct, and—above all—fast. But the Rust compiler isn’t always the fastest car in the garage. The larger a Rust program is, and the more dependencies it has, the longer its compile time will be. A development process that once was a sprint slows to a creep.

Now for the good news: None of this is inevitable. Used smartly, many of the slowest parts of the Rust toolchain can be made quite snappy. Here’s a compendium of common techniques for speeding up Rust compilation. They are organized by strategy and general theme, and you can put them to work right now in your Rust projects.

1. Start with the basics

The single most effective thing you can do without changing anything about your existing work habits is to keep your Rust toolchain updated. You may already be doing this, but it’s worth a reminder.

Running rustup update periodically ensures you’re using the latest version of the compiler. This matters because Rust’s compiler team is constantly updating and optimizing the compilation process. Those optimizations aren’t just rolled into rustc itself, but also into LLVM, the framework rustc builds on top of.

If you’re reluctant to update the toolchain aggressively, because it might affect your project’s requirements, pin your project toolchain to a specific version, like so:

[toolchain]
channel = "1.85"

2. Don’t do anything you don’t have to

The golden rule of performance in computing, no matter what you’re doing: the less you do, the better. This absolutely applies to compiling Rust projects, since very often, a complete compilation isn’t needed.

Instead of a full compilation, you can run cargo check to perform most of the checks you need. This will ensure your code would compile, without having to actually compile the code. The former chiefly involves rustc’s checking mechanisms; the latter involves the LLVM-driven build process, which is far slower.

Note that cargo check will not skip compilation of as-yet-unbuilt dependencies. If they need to be built to run the check, they will be. But after the first cargo check to get caught up on that process, future check runs will complete far faster.

Another common way to avoid rebuilding is to use a compiler caching tool. The sccache project supports caching Rust compiler artifacts, along with several other popular languages with similar coompiler behaviors (C, C++, etc.). However, you get the best results with sccache or something like it when you use it as a build cache for multiple users—e.g., a development team in an organization with a shared file system. Used on one system alone, it doesn’t yield much of an advantage, unless you’re sharing build artifacts for the same versions of crates across multiple projects.

Another powerful way to avoid unneeded compilation is to wrap your dependencies as dynamically linked libraries (“dynlibs”). This isn’t native to Rust’s toolchain, though—it’s accomplished with a third party tool, cargo add-dynamic. Using the tool means you won’t get some of the benefits of compiling dependencies statically, like being able to inline code from crates. But it also speeds up the linking process dramatically, and while linking does get pushed off to runtime, its costs are typically minimal. The creator of cargo add-dynamic has written in detail about the ins and outs of this technique, using the polars data science library as an example.

3. Divide and conquer

The larger a project is, the less likely you need to recompile the entire thing if it’s divided along clean architectural lines. If you have a project with an MVC design, and you’re only making changes to the views that don’t involve altering its APIs, you can just recompile that portion of the project as you alter it.

To achieve something like this in Rust, you’d split up your project into multiple subcrates using Cargo workspaces. You’ll need to manually refactor existing single-crate projects, as there’s no native automated way to do this (unless you ask your friendly neighborhood LLM to help!). You’ll also benefit most from this selective recompilation in a project where you can split the codebase cleanly across well-defined boundaries, and where the project is big enough to justify partitioning. This blog post describes a fantastic (if extreme) application of this principle to efficiently compile SQL code converted at scale to Rust.

Another potential divide-and-conquer technique is parallel compilation, which is slowly becoming a feature that’s supported “out of the box” in the Rust compiler, instead of something you need to enable manually. If you use parallel compilation nightly, more of the parallel features are enabled by default; otherwise, you can use the compiler flag -Z threads= to enable it manually, where is how many threads to use.

To that end, don’t put too much emphasis on manually adding parallel code generation unless it provides a demonstrable benefit. One way to test this would be to run a completely clean build with parallelism at both full and half utilization—e.g., for an 8-core system, use 8 and 4 threads for the build process—and see if there’s any discernable benefit.

4. Analyze, analyze, analyze

It’s hard to know what to optimize without measurements. Fortunately, Rust’s cargo build comes with a powerful build-time reporting tool, the --timings switch. Run it and you’ll get a detailed HTML-formatted report that can help you pin down exactly what’s taking so long in the compilation process.

Sometimes the culprit isn’t merely in a given crate, but in a procedural macro used by some crate. A nightly-only flag for the compiler, -Zmacro-stats, generates information about the number of lines of code a given macro generates. This tells you how much code is being expanded from macros. That information may be a hint as to why a given crate may be the source of unexpectedly high compile times.

Another useful measure is to gauge how long each compilation step takes. The -Z time-passes compiler flag displays the elapsed time for each step, including LLVM’s overhead and the work done by the linker. Don’t sleep on how much time the linker takes; it’s an oft-underrated choke point for compilation. You can try switching linkers—experiment with lld or mold to see if your link times pick up.

5. Use platform-specific optimizations

If you’re stuck using Microsoft Windows (or if you actually want to use it), software projects belong on a new file system created specifically for development scenarios. The Dev Drive, as it’s called, uses a new file system, called ReFS, which has more proactive automatic-repair behavior (you don’t need to manually scan volumes), and also automatically reduces interference from Windows’s antivirus scanning.

Linux users can set up an in-memory temporary filesystem and use it for fast caching of compiled artifacts. The downside: Anything stored there is lost after rebooting. However, if you keep long uptimes for your workstation, you’ll only need to rebuild the cache once after rebooting.

Conclusion

The Rust compiler team keeps making strides to improve compilation times without requiring intervention from the developer. But there will always be places where the compiler alone can’t do the heavy lifting to make things faster. The more proactive you are about discovering where your project is slow to compile, the faster your Rust software will be.

(image/jpeg; 0.37 MB)

Anthropic expands Claude Code beyond developer tasks with Cowork 14 Jan 2026, 8:56 am

Anthropic has introduced Cowork, a research-preview feature aimed at extending Claude Code’s capabilities beyond programming to everyday enterprise workflows.

The new flavor of the coding assistant will enable users to automate tasks such as summarizing calendars, creating reports, and organizing files, once an organization provides it access to a particular folder. Cowork can also connect to relevant tools, databases, and applications.

It can even be paired with Claude in Chrome to complete tasks that require browser access, the company wrote in a blog post, adding that users can assign tasks in parallel without waiting for the AI-based assistant to finish a particular task.

Useful for a wider range of functions

The introduction of Cowork, according to analysts, signals Anthropic’s push to make AI assistants useful for a wider range of business functions.

“Cowork reflects an intent to make Claude materially useful in everyday enterprise workflows by moving beyond conversation to scoped action, particularly around document and file-centric work that dominates knowledge roles,” said Vershita Srivastava, practice director at Everest Group.

Roles such as research, project management office (PMO), operations, and analytics, where guardrails can be clearly defined, can also reap benefits from the new tool and will probably see the most uptake, Srivastava added.

Seconding Srivastava, The Futurum Group’s practice leader for data, AI, and infrastructure, Bradley Shimmin pointed out that Cowork could be useful for developers as well and can be seen as a natural evolution of Anthropic’s “computer-use” capability and command-line utilities.

Since Cowork can access core operating system functionality, rather than just using a browser to look at your computer system and take pictures of your screen, it can be used to automate and operationalize tasks that sit adjacent to the agentic software development workflows, Shimmin said.

“For example, you may want to take some JSON data that is part of a project and quickly convert it into a markdown format so that non-developers can easily read that information.”

However, Anthropic has warned that giving Cowork access to a system or environment requires caution, as it can misunderstand prompts and end up executing “destructive” commands, such as deleting files, although it does ask users before executing a command or task.

The company also flagged the risk of prompt injection attacks, where malicious content could alter Claude’s plans despite the tool’s built-in defenses.

To counter such issues, Anthropic could build in an undo feature allowing users to retrieve files when deleted or un-send an email when the product is made generally available, said Jason Andersen, principal analyst at Moor Insights and Strategy.

The undo feature would take care of both prompt injection attacks as well as human error, Andersen added. Currently, the new flavor of the assistant is available to Claude Max subscribers via the macOS application.

(image/jpeg; 2.12 MB)

Java 27 gets its first feature 13 Jan 2026, 9:31 pm

Java Development Kit (JDK) 27, a release of standard Java planned for arrival in September, already has a feature proposed for it: a post-quantum hybrid key exchange capability to bolster network security.

The feature, post-quantum hybrid key xxchange for TLS 1.3, was listed on the OpenJDK page for JDK 27 on January 13. It would enhance the security of Java applications requiring network communications by implementing hybrid key exchange algorithms. These algorithms defend against future quantum computing attacks by combining a quantum-resistant algorithm with a traditional algorithm. Applications that use javax.net.ssl APIs will benefit from the improved algorithms by default, without change to existing code, according to the JEP (JDK Enhancement Proposal).

JDK 27 will be a non-LTS (Long-Term Support) release backed by six months of support, the same as JDK 26, which is due March 17. The current standard Java release, JDK 25, is an LTS release backed by multiple years of support. Other possible features for JDK 27 are preview features in JDK 26. These include:

Another strong possibility is the Vector API, now being incubated in JDK 26. Oracle, the steward of standard Java, last week detailed its plans for improving Java in 2026, with work on features such as value types, structured concurrency, and AOT (ahead-of-time) compilation. These features may not necessarily arrive in 2026, however.

(image/jpeg; 7.49 MB)

Google’s Universal Commerce Protocol aims to simplify life for shopping bots… and devs 13 Jan 2026, 1:01 pm

Google has published the first draft of Universal Commerce Protocol (UCP), an open standard to help AI agents order and pay for goods and services online.

It co-developed the new protocol with industry leaders including Shopify, Etsy, Wayfair, Target and Walmart. It also has support from payment system providers including Adyen, American Express, Mastercard, Stripe, and Visa, and online retailers including Best Buy, Flipkart, Macy’s, The Home Depot, and Zalando.

Google’s move has been eagerly awaited by retailers according to retail technology consultant, Miya Knights. “Retailers are keen to start experimenting with agentic commerce, selling directly through AI platforms like ChatGPT, Gemini, and Perplexity. They will embrace and experiment with it. They want to know how to show up and convert in consumer searches.”

Security shopping list

However, it will present challenges for CIOs, in particular in maintaining security, she said. UCP as implemented by Google means retailers will be exposing REST (Representational State Transfer) endpoints to create, update, or complete checkout sessions. “That’s an additional attack surface beyond your web/app checkout. API gateways, WAF/bot mitigation, and rate limits become part of checkout security, not just a ‘nice-to-have’. This means that CIOs will have to implement new reference architectures and runtime controls; new privacy, consent, and contracts protocols; and new fraud stack component integration.”

Info-Tech Research Group principal research director Julie Geller also sees new security challenges ahead. “This is a major shift in posture. It pushes retail IT teams toward deliberate agent gateways, controlled interfaces where agent identity, permissions, and transaction scope are clearly defined. The security challenge isn’t the volume of bot traffic, but non-human actors executing high-value actions like checkout and payments. That requires a different way of thinking about security, shifting the focus away from simple bot detection toward authorization, policy enforcement, and visibility,” she said.

The introduction of UCP will undoubtedly mean smoother integration of AI into retail systems but, besides security challenges, there will be other issues for CIOs to grapple with.

Geller said that one of the issues she foresees with UCP is that “it works too well”. By this she means that the integration is so smooth that there are governance issues. “When agents can act quickly and upstream of traditional control points, small configuration issues can surface as revenue, pricing, or customer experience problems almost immediately. This creates a shift in responsibility for IT departments. The question stops being whether integration is possible and becomes how variance is contained and accountability is maintained when execution happens outside the retailer’s own digital properties. Most retail IT architectures were not designed for that level of delegated autonomy.”

Google’s AI rival OpenAI launched a new feature last October that allowed users to discover and use third-party applications directly within the chat interface, at the same time publishing an early draft of a specification co-developed with Stripe, Agentic Commerce Protocol, to help AI agents make online transactions.

Knights expects the introduction of UCP to accelerate interest in and adoption of agentic commerce among retailers. “Google said that it had already worked with market leaders Etsy, Wayfair, Target, and Walmart to develop the UCP standard. This will force competitors to accelerate their agentic commerce strategies, and will help Google steal a march on competitors, given that it is the market leader,” she said.

For online retailers’ IT departments, it’s going to mean extra work, though, in implementing the new protocols and in ensuring their e-commerce sites are visible to consumers and bots alike.

(image/jpeg; 1.04 MB)

From distributed monolith to composable architecture on AWS: A modern approach to scalable software 13 Jan 2026, 10:00 am

In today’s fast-paced digital landscape, building agile, scalable and maintainable software systems is paramount. Organizations often start with monolithic applications for their simplicity, but soon face challenges as these systems grow more complex. A distributed monolith, where the application is split into components but remains tightly coupled and interdependent, can hamper agility and scalability. Transitioning from this state to a composable architecture on AWS empowers teams to deliver resilient, scalable and business-aligned software solutions.

This article walks through the conceptual and practical journey of moving from a distributed monolith to a composable architecture on AWS, highlighting key principles, architectural patterns, AWS services and operational practices.

Understanding the distributed monolith problem

A distributed monolith is a system composed of multiple services or components, deployed independently but tightly coupled through synchronous dependencies such as direct API calls or shared databases. Unlike a true microservices architecture, where services are autonomous and loosely coupled, distributed monoliths share many pitfalls of monoliths, including:

  • Tight coupling: Components depend heavily on the internals of others, creating fragile dependencies.
  • Deployment friction: Changes require coordinated deployments across services.
  • Operational complexity: Dysfunctional distributed components make troubleshooting and scaling difficult.
  • Slow innovation: Teams struggle to iterate rapidly due to the interconnected system nature.

These issues arise when teams attempt to scale monolithic applications prematurely without fully embracing decoupling and domain-driven principles.

Principles of composable architecture

Composable architecture embraces modularity and loose coupling by treating every component as an independent building block. The focus lies in business alignment and agility rather than just code decomposition.

Key characteristics

  • Independent deployability: Each component or microservice can be developed, deployed and scaled independently.
  • Domain-driven design (DDD): Using bounded contexts and ubiquitous language to define clear service boundaries aligned with business domains.
  • API-led communication: Interactions happen via well-defined APIs or event-driven messaging, avoiding direct code or database sharing.
  • Data decentralization: Each service manages its own data to prevent tight coupling through shared databases.

These principles enable systems where components can be composed, replaced or upgraded without impacting the whole system.

AWS services enabling composable architecture

AWS offers a rich ecosystem tailored for building composable systems:

  • AWS Lambda: Serverless compute enabling event-driven, stateless functions as microservices.
  • Amazon API Gateway: Creating and managing APIs for service communication.
  • Amazon DynamoDB: A NoSQL database that supports single-table design for efficient data access per service.
  • Amazon EventBridge: Event bus enabling loosely coupled event-driven architectures.
  • AWS Step Functions: Orchestrating workflows across microservices.
  • AWS Cloud Development Kit (CDK): Infrastructure as code for automated, repeatable service deployments.
  • Amazon SNS/SQS: Messaging services for asynchronous communication between components.

These services help build fully decoupled architectures with scalable and maintainable infrastructure.

The transformation journey, step-by-step

1. Assess and identify boundaries

Start by analyzing the existing application to find natural business or functional boundaries. Use Domain-Driven Design to define bounded contexts that encapsulate specific business capabilities.

Aim to reduce inter-service dependencies by identifying:

  • Shared databases that need decoupling.
  • Synchronous calls that can be turned into asynchronous messaging.
  • Code or library dependencies crossing service boundaries.

2. Separate and modularize codebase

Refactor the code into separate repositories or modules, each representing a bounded context or microservice. This clear separation supports independent deployment pipelines and ownership.

import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as apigw from 'aws-cdk-lib/aws-apigateway';

export class OrderServiceStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const orderLambda = new lambda.Function(this, 'OrderHandler', {
      runtime: lambda.Runtime.NODEJS_18_X,
      handler: 'order.handler',
      code: lambda.Code.fromAsset('lambda/order-service'),
    });

    new apigw.LambdaRestApi(this, 'OrderAPI', {
      handler: orderLambda,
      restApiName: 'Order Service',
    });
  }
}

Consolidate infra-as-code with AWS CDK to manage each microservice’s infrastructure, including APIs, storage and permissions.

3. Implement API-first communication

Replace direct code or database calls with API calls or events. For example:

  • Use REST or GraphQL APIs via API Gateway.
  • Emit business events via EventBridge or SNS for asynchronous processing.

Use SQS for message queuing to handle transient workloads.

const AWS = require('aws-sdk');
const eventBridge = new AWS.EventBridge();

exports.handler = async (event) => {
  const orderDetails = event.detail;

  const params = {
    Entries: [
      {
        Source: 'order.service',
        DetailType: 'OrderCreated',
        Detail: JSON.stringify(orderDetails),
        EventBusName: 'default',
      },
    ],
  };

  await eventBridge.putEvents(params).promise();

  return { statusCode: 200, body: 'Order event sent' };
};

This shift fosters loose coupling and enables scalability.

4. Decentralize data ownership

Assign each microservice its own DynamoDB table or data store. Avoid cross-service database joins or queries.

Adopt a single-table design in DynamoDB to optimize data retrieval patterns within each service boundary. This approach improves scalability and performance at the data layer.

5. Migrate incrementally

Migrating a distributed monolith at once is risky. Instead:

  • Start with migrating low-risk or well-bounded components.
  • Implement a strangler pattern to route traffic gradually to new microservices.
  • Refactor and evolve incrementally while monitoring performance and errors.

Use Case: Migrating an e-commerce platform

An e-commerce platform began as a large monolith with intertwined order processing and customer management. Source

Challenge: Frequent downtime due to deployment coupling; slow feature delivery.

Approach

  • Applied Domain-Driven Design to split Order, Customer and Payment domains.
  • Used AWS Lambda and API Gateway for new microservices.
  • Deployed EventBridge for asynchronous events like OrderPlaced, triggering inventory updates.
  • Adopted DynamoDB single-table design per microservice.

Outcome: Reduced deployment risk, improved team autonomy and scaled individual services based on demand.

Benefits of Composable Architecture on AWS

  • Improved agility: Teams can develop and deploy services independently, accelerating release cycles.
  • Scalability: Scale services on demand based on their usage patterns.
  • Resilience: Failures remain isolated, reducing system-wide outages.
  • Operational simplicity: Decoupling simplifies troubleshooting and makes infrastructure management easier.
  • Business alignment: Services reflect real-world domains, improving code understanding and maintenance.

Challenges and Considerations

A composable architecture also introduces complexity:

  • Increased operational overhead: Managing many services requires sophisticated CI/CD, monitoring and automation.
  • Proper observability: Monitoring your services, application and infrastructure is also very critical and you can use some full-stack observability tools such as those reviewed and rated by Gartner’s Peer Insights.
  • Security: More communication points demand stringent security measures.
  • Data consistency: Eventual consistency and distributed transactions need careful design.
  • Skill requirements: Teams must be proficient with distributed systems, cloud-native patterns and AWS tooling.

These challenges can be mitigated with proper tooling, automation and training.

Conclusion

Transitioning from a distributed monolith to a composable architecture on AWS is a strategic journey that demands careful planning and execution. By applying domain-driven design principles, leveraging AWS’s serverless and managed services and embracing modular, loosely coupled components, organizations can build scalable, resilient and flexible software systems aligned with evolving business needs. This transformation not only solves traditional monolithic pain points but also unlocks agility and innovation potential critical for today’s competitive environment.

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

(image/jpeg; 8.43 MB)

Why hybrid cloud is the future of enterprise platforms 13 Jan 2026, 9:00 am

For years, enterprises enthusiastically adopted a cloud-first approach, eager to take advantage of the flexibility and rapid innovation public cloud platforms offered. But as artificial intelligence operations transition from experiments to business imperatives, organizations are discovering that the old assumptions about where AI belongs (primarily in the public cloud) no longer hold true. AI is, in fact, becoming the great normalizer of platform selection. Its unprecedented costs, demands for low latency, and new concerns about resilience and data sovereignty are pushing enterprises to reconsider the cloud as the default choice for their most strategic workloads. Having long advocated this perspective, even as it ran counter to prevailing wisdom, I’m heartened to see industry consensus shifting in this direction.

AI workloads are different from traditional applications in many ways, most notably their hunger for compute and data. Running large-scale training or inference jobs in the public cloud can quickly lead to skyrocketing costs, sometimes outstripping what comparable on-premises infrastructure would demand. According to Deloitte, “some enterprises are seeing monthly [cloud] bills in the tens of millions,” with costs often surpassing 60% to 70% of the total cost to acquire and maintain equivalent on-premises systems. That kind of economic pressure openly challenges the cloud-first edict, particularly when predictability and budget control are required.

Moreover, AI’s need for ultra-low latency to support operations such as real-time decision-making and its requirement for reliable, always-on performance in mission-critical environments often make on-premises solutions more viable. The same Deloitte report observes that “applications requiring response times of 10 milliseconds or below cannot tolerate the inherent delays of cloud-based processing.”

Conventional, not controversial

It wasn’t so long ago that expressing skepticism about cloud-only strategies drew resistance. For the better part of a decade, cloud held near-religious status in enterprise strategy meetings. I recall regularly making the case for hybrid cloud, influenced not by nostalgia but by a pragmatic understanding of the architectural realities many organizations faced. Today, it’s clear that more decision-makers and respected consulting voices are coming to similar conclusions.

Notably, Deloitte’s analysis now explicitly recommends a “three-tier approach” that combines cloud for elasticity, on-premises for consistency in production workloads, and edge deployments for immediate or ultra-low-latency AI needs. This is architecture tailored for a world where AI—not generic IT workloads—drives technology decisions. ZDNet, summarizing these industry movements, notes that “cloud-first strategies can’t handle AI economics,” and forward-looking companies are now “contemplating a shift away from mainly cloud to a hybrid mix of cloud and on-premises.”

AI as the platform equalizer

The radical resource requirements and operational constraints of AI have stripped away much of the mythology that cloud is best for everything or that on-premises is purely legacy. Every choice is now fundamentally workload-driven: AI must go where it can run most cost-effectively, safely, and responsively. Sometimes that’s in the cloud; just as often, it’s in non-cloud deployments or a combination thereof.

This new reality is forcing organizations to undertake careful assessments before making platform decisions for AI. The days when IT leaders could simply sign off on wholesale cloud migrations, confident it was always the most strategic choice, are over. In the age of AI, the optimal approach is usually hybrid.

Having openly championed this hybrid path even when it was unpopular, I welcome the growing acceptance of these ideas among decision-makers and industry analysts. Enterprises now have a rationale for an integrated, best-of-both-worlds platform, not as a retreat from cloud, but as a progression toward mature, sustainable AI. Hybrid approaches allow organizations to optimize costs, address regulatory and latency needs, and retain vital security controls, while also continuing to leverage the cloud’s strengths for experimentation and growth.

Artificial intelligence, with its intense resource demands and complex risk profile, has normalized a pragmatic approach to platform architecture. Ignore the rhetoric. Hybrid is the future for organizations that intend to scale AI, strike the right cost-performance balance, and adapt to ever-changing requirements. With authoritative references both validating and reinforcing this view, it’s clear that what was once dissent is now fast becoming conventional wisdom. I’m pleased to witness this change. Proof that the path to successful AI lies not in cloud-only solutions, but in the thoughtful combination of cloud and non-cloud strategies.

(image/jpeg; 0.57 MB)

Which development platforms and tools should you learn now? 13 Jan 2026, 9:00 am

Software development used to be simpler, with fewer choices about which platforms and languages to learn. You were either a Java, .NET, or LAMP developer. You focused on AWS, Azure, or Google Cloud. Full-stack developers learned the intricacies of selected JavaScript frameworks, relational databases, and CI/CD tools.

In the best of times, developers advanced their technology skills with their employer’s funding and time to experiment. They attended conferences, took courses, and learned the low-code development platforms their employers invested in.

Only now are many developers realizing they must radically upskill due to new AI capabilities. Others may be out of work and should use the time to develop new skills to improve their employability. AI is taking a bite out of employment, and more than 100,000 tech employees have been laid off in 2025, according to layoffs.fyi.

As more coding is done with code generators, vibe coding tools, and low-code automation platforms, the choice of what to learn isn’t straightforward.

Gauging the market for new skills

Should developers follow their passions and interests? Or is it more pragmatic to review what skills and certifications are in demand and focus your learning in these areas?

Developers should look beyond today’s job specifications and anticipate where demand is likely to grow over the next few years. As more enterprise platforms deliver agentic AI capabilities, there will be a shift in what businesses will develop themselves and which platforms they invest in. 

“When evaluating where to build skills, developers should look beyond tools and focus on ecosystems that foster learning, collaboration, and adaptability,” says Gloria Ramchandani, SVP of product at Copado. “Choose platforms that encourage experimentation across low-code, automation, and cloud development, because the future favors hybrid roles that blend creativity, technical depth, and soft skills. Invest in communities where you can learn from peers, share best practices, and grow with technology.”

Ways to track the skills market include the Stack Overflow Developer Survey and the State of Developer Ecosystem Report. Review DORA’s State of AI-Assisted Software Development and Stanford University’s AI Index Report for detailed benchmarks on AI models and platforms.

Junior developers should go deep fast

Developers should also optimize learning based on their experience levels. One strategy for junior developers is to broaden their skill set and go deep into implementation details. Junior developers should prioritize learning tools that go deep into a skill or tool without requiring a significant time investment.

“New or junior developers, as strange as this may sound, should pick up tools that are well covered with YouTube tutorial videos,” says Matthew Makai, VP of developer relations at Digital Ocean. “No-code and low-code tools, IDEs, and developer services are difficult to learn from text-based tutorials alone. Videos can show you specific ways that more experienced developers use those tools that you can readily copy to build your own projects.”

A second consideration for junior developers is to learn new implementation domains. For example, application developers may want to learn more about API development, data pipelines, platform integrations, and AI agent development to demonstrate a broad range of software development skills.

“When choosing which new platforms to learn, focus on durable thinking over transient tools,” says Facundo Giuliani, developer relations engineer at Storyblok. “The most valuable skills lie in understanding system design, data flow, and how to combine automation, AI, and APIs to create outcomes. Low-code and no-code tools are great entry points, but the long-term edge comes from mastering composability, reasoning, and interoperability—the skills that apply across any emerging tech stack.”

Dave Killeen of Pendo recommends this test for developers evaluating platforms: Can you go from idea to working prototype in under a day with this platform? “The platforms worth mastering are the ones that collapse the feedback loop. Whether it’s low-code, AI-assisted development, or cloud platforms, choose what helps you iterate and validate assumptions in hours, not sprints.”

Preparing for senior-level dev responsibilities

Developers looking to advance to senior-level roles, or those already at that level, need to demonstrate a strong understanding of software engineering principles.

“Developers should focus on platforms that build transferable skills and teach core concepts like API integration, workflow automation, and modular design rather than locking them into one ecosystem,” says Phillip Goericke, CTO of NMI. Seek technologies that reinforce abstraction layers and extensibility, showing how concrete implementations emerge from abstract ideas. Prioritize environments that enable rapid prototyping and scalable, secure design, strengthen understanding of common programming structures, and develop critical thinking to narrow focus when solving real problems.”

Josh Mason, CTO of Recordpoint, adds, “Optimize for skills that travel: machine learning concepts, data modeling, API design, testing, and security.”

Developers must also explore how to use generative AI tools to write agile requirementsdevelop softwareautomate testingmaintain documentation, and drive other efficiencies across the software development life cycle (SDLC). Developer experiences are evolving from IDEs focused on writing code to natural language dialogs, code validation tools, and AI agents performing development tasks. 

“AI SDLC tools are just another new way for developers to use powerful assistants in their development pipelines, much like the modern IDE,” says Simon Margolis, associate CTO of AI and machine learning at SADA. “The developer’s core goal doesn’t change: applying logic to command tools, whether using English and Gemini CLI or writing Python directly.”

Diving into SaaS and low-code development

Some developers have staked their careers on building skills and delivering results from enterprise SaaS platforms. On the other hand, some developers have focused on pro-code development and open source frameworks, leaving low-code and proprietary platforms aside.

Developers should cast a wide net when learning to increase job opportunities and be open-minded about platforms, especially if they want to work in large enterprises. Some enterprise SaaS platforms with extended development capabilities include SAP, Salesforce, and Workday. Here’s a primer on the breadth of their development capabilities.

Developers should also consider learning enterprise-ready low-code platforms that embrace AI, such as Appian, OutSystems, Pega, and Quickbase.

“The biggest hurdle is not understanding the platform, and actually, the tool set in most platforms is pretty simple,” says Matt Grippo, SVP of core software at Workday. “The part that takes a little bit more knowledge is understanding the environment, the security model, and the business processes you have to work with.”

With LLMs and agentic AI capabilities being introduced by SaaS and low-code development platforms, developers may be considering whether learning them is a smart career path.

“I don’t believe that AI will replace developers,” says Dr. Philipp Herzig, CTO at SAP SE. “AI can generate code, but the abstraction is only as good as understanding what’s going on under the hood. There are tons of new challenges in this new AI stack, so while it’s easy to get started, much hard work is still required to make it enterprise-ready, make it at scale for the organization, and that’s where the complexity lies.”

Focus on the role, not just the tools

Developers looking to upskill should also focus on going upstack. Coding is a means of solving business challenges, testing new ideas, developing new customer experiences, automating workflows, delivering insights from data, and enabling innovation. In addition to coding skills, companies will expect developers to have strong business acumen and to participate more in agile planning for what gets developed.

“Technology will keep evolving, but your real edge is curiosity, critical thinking, and how you build with purpose,” says Christian Birkhold, VP of product management at KNIME. “Master AI to move faster, but never stop understanding what it builds. Sweat the details, stay close to the code, and master the fundamentals—that’s how you stay in control when everything else accelerates.”

Developers must embrace lifelong learning, as the problems to be solved, the tools, and the business opportunities are changing rapidly because of AI. Developers must learn new software development tools, strengthen their understanding of AI capabilities, and adopt a solutions-oriented mindset to expand their devops career paths.

(image/jpeg; 19.58 MB)

Oracle unveils Java development plans for 2026 13 Jan 2026, 2:56 am

Oracle’s Java team in 2026 will work toward milestones including a preview of value types, an incubation of code reflection, shipping AOT (ahead-of-time) code compilation, and finalizing the structured concurrency API.

These efforts and many others under OpenJDK projects such as Project Loom, for exploring JVM (Java Virtual Machine) features and APIs for implementing lightweight user-mode threads, and Project Valhalla, for augmenting the Java object model with value objects, were cited in a January 8 video presentation by Nicolai Parlog, a Java developer advocate at Oracle. Work on these features, though, does not imply they will be released in 2026.

AOT code compilation is part of Project Leyden, which is intended to improve startup time, time to peak performance, and the footprint of Java programs. The goals for AOT code compilation include improving startup and warmup time by making native code from a previous application run instantly available, when the HotSpot JVM starts. Project Leyden also will explore code cache portability and iterative training, allowing frameworks to train the cache. Inspectability of training data also will be examined.

Plans for Project Amber, which focuses on producing smaller, productivity-oriented Java language features, include exploring string templates and filing JEPs (JDK Enhancement Proposals) for constant patterns and interfaces. There may also be updates on record-esque classes and interfaces and on more inclusive pattern matching.

With Project Loom, Parlog said that the structured concurrency API, for concurrent programming, will preview with small changes in JDK 26 and will likely be finalized by the end of the year. Currently in a rampdown phase, JDK 26 is due for a production release on March 17. Also on the agenda for Loom is exploring more applications of virtual threads.

For Project Panama, which focuses on improving connections between the JVM and non-Java APIs, the vector API planned for JDK 26 will see its 11th incubation. Also on the agenda for Panama in 2026 are general improvements to the jextract tool for parsing header files of native libraries and generating code. Improvements also are eyed for the Foreign Function and Memory API, which enables Java programs to interoperate with code and data outside the Java runtime.

For Project Babylon, which aims at extending Java to foreign programming models such as SQL, plans include incubating code reflection, which allows third-party frameworks to reflect over Java code in a lambda expression and process it. The Babylon team will also be working on proofs of concept for using code reflection to run machine learning models on the GPU.

With Project Valhalla, developers will work to deliver a preview of value types in the second half of this year, after which work will focus on null-aware types, array improvements, and unification of primitives and wrappers. Value objects are class instances that have only final fields and lack object identity. They allow developers to opt into a programming model for domain values in which objects are distinguished solely by the values of their fields.

(image/jpeg; 4.3 MB)

Page processed in 0.319 seconds.

Powered by SimplePie 1.4-dev, Build 20170403172323. Run the SimplePie Compatibility Test. SimplePie is © 2004–2026, Ryan Parman and Geoffrey Sneddon, and licensed under the BSD License.