Agustin Barrientos
All posts

The Brief #26.44 · Firefox 159, a critical PHP fix, and GPT-6.1 Terra

Want more of these in your Google results?

With Firefox 159 out, scroll-driven animations and scoped custom element registries now work in every major browser.

Moonshot and OpenAI released Kimi K3.1 Pro and GPT-6.1 Terra, Chrome shows a warning page for sites on plain HTTP, and PHP fixed two bugs that let attackers run code on your server.

Then there’s Google’s A2UI Express, OpenAI and Claude on Google Cloud, and the latest decision models.

Kimi K3.1 Pro and GPT-6.1 Terra

Moonshot released Kimi K3.1 Pro on October 23. It’s Kimi K3 after a lot more training. Artificial Analysis scored it 55 on its Intelligence Index, at $2.11 a task.

On the Kimi API it costs $2 input / $10 output per million tokens, less than the $3 input / $15 output Moonshot charges for Kimi K3. Moonshot says its Highspeed version runs 2 to 3 times faster, for $4 input / $20 output per million tokens.

Moonshot plans to release the weights by November 4. Until then, you can use it through Moonshot, in its Kimi apps or on the Kimi API.

GPT-6.1 Terra came out on October 26. OpenAI made it for reading screenshots and technical drawings or filling out forms. It’s also meant for writing and computer use (when the model clicks and types in apps for you). It costs $1 input / $5 output per million tokens, half of what GPT-6.1 Sol costs.

OpenAI says in its post that Sol and GPT-6 Astra are still the better choice for the most complex coding tasks.

Terra got 48 on the Intelligence Index at max effort, at $0.40 a task. That’s 4 points below Sol for a little more than half of Sol’s $0.72.

Terra supports tool calling (when the model calls a function in your code, like a search) in OpenAI’s newer Responses API but not in the older Chat Completions API. If your app calls tools through Chat Completions, you’ll have to move that code to the Responses API before you switch models.

You can also pick Terra in ChatGPT Work, Codex, and GitHub Copilot, on most paid plans.

I also added a ⁠Decision models⁠ section this week.

Table Intelligence Index
#ModelIntelligence IndexCost per Index task
1Claude Opus 5.5 (max)58$5.98
2Claude Sonnet 5.5 (max)56$5.46
3Muse Wonder Full (max)56No API price
4Kimi K3.1 ProNew55$2.11
5Claude Opus 5.5 (high)54$1.82
6Claude Fable 5.1 (max)53$7.63
7GPT-6 Astra (max)53$3.26
8Gemini 4 Argon (high)53$1.62
9Muse Wonder (max)52$3.27
10GPT-6.1 Sol (max)52$0.72
11Claude Fable 5.1 (high)51$3.91
12GPT-6.1 Terra (max)New48$0.40
Table Decision Index
#ModelDecision IndexCost per million tasks
1d1-ultra65$31.80
2SubQ Snap 1.1New65$30.34
3Elephant 9BNew65$8.39
4Jev 1.1457$41.53
5Decider v1.256$15.14
6GLiDE54$119.02
7Microsoft-Decision-154$30.71
8Mercury Decide53$15.20
9Celeris-1 Decision52$31.57
10d150$15.14
Chrome’s Decisions API (Gemma 4 on CPU)Not scored$0

Firefox 159

Firefox 159 came out on October 27 with scroll-driven animations and scoped custom element registries. Chrome and Safari already had both, so they now work in all three browsers.

Scroll-driven animations move with the scroll position instead of with time, like a reading progress bar that fills up as you scroll down the page. I wrote about them in July, in How animation-timeline: scroll() Replaces Scroll JavaScript.

At the time, Firefox was the one browser where that article’s reading progress bar stayed empty. In Firefox 159, that bar works like it does in Chrome and Safari.

Scoped registries are for custom elements. Without them, each page has one registry, a single list of custom elements called customElements, where a name can only be defined once.

If two libraries on the same page both define <ui-button>, the second customElements.define() call throws an error. Every <ui-button> on the page ends up with the first library’s version. That can happen if a page loads two design systems, or two versions of the same one.

With a scoped registry, a component gets its own list of custom elements inside its shadow root. You create the registry with new CustomElementRegistry() and define your elements on it. Then you pass it to attachShadow(), the method that creates the shadow root. A <ui-button> inside that shadow root uses the scoped definition, even if the page already has a different <ui-button>.

js
// A registry for this component only.
const registry = new CustomElementRegistry();

// The component's own ui-button, defined in that registry.
registry.define( 'ui-button', class extends HTMLElement {
	connectedCallback() {
		this.textContent = 'Scoped button';
	}
} );

// The element that holds the component on the page.
const $host = document.createElement( 'div' );
document.body.append( $host );

// The shadow root gets the component's registry.
const shadow = $host.attachShadow( {
	mode: 'open',
	customElementRegistry: registry,
} );

// This ui-button gets the scoped definition.
shadow.innerHTML = '<ui-button></ui-button>';

Chrome added scoped registries in version 146, and Safari in version 26.

Mozilla also plans to turn on random() in Firefox 161, due on November 24. That would make the CSS function for random values work in every major browser. It’s been in Chrome since version 156 and in Safari since 26.2.

HTTP warnings in Chrome

On October 21, Google said that Chrome now shows all users a warning page before it connects to a site over plain HTTP, and doesn’t go on until the user allows it. Over plain HTTP, anyone on the network between you and the site can read or change the page and whatever you send, because nothing is encrypted.

The warning first came on earlier in 2026, only for people using Enhanced Protection, the strictest of Chrome’s Safe Browsing settings. Google made it the default with Chrome 154 on September 22.

The browser switches an address to HTTPS by itself, and shows the warning page if the site doesn’t support HTTPS. After you approve a site the first time, you won’t see the warning for it again unless you go at least two weeks without visiting it.

Chrome’s security team explains that the “Not Secure” label in the address bar shows up after the data is already exposed, and never on a redirect that passes through an HTTP address on the way to another page. In Google’s early rollout data, nearly 95% of desktop users didn’t see any HTTP warning in a given week. Google says Chrome is the first browser to make this change.

If a link you own goes through a domain without HTTPS, like an old tracking redirect in an email or the short link on a printed QR code, people who follow it in Chrome see that warning page first. Check that all the domains in those links serve HTTPS, including the ones that only redirect.

PHP2Shell

PHP released versions 8.5.12, 8.4.27, 8.3.36, and 8.2.35 on October 21 to fix two critical bugs in the PHP engine, CVE-2026-109618 and CVE-2026-109619. Both let an attacker run any code they want on a server without logging in. The security company Wiz found them and calls them PHP2Shell.

WordPress and Drupal run on PHP. Because the bugs are in PHP itself, an app on an affected version is exposed whatever the app’s code does.

Google Cloud’s post lists every version from 5.4 through 8.5.11 as vulnerable. The PHP team says the risk is highest for PHP running inside the Apache web server through mod_php, where a demonstrated attack works before any of the app’s code runs.

Google Cloud’s post says Gemini 4 Argon, one of the models Wiz used in its research, helped a lot to find the bugs and build the exploit, and to check the fix afterward. OpenAI says a team called Calif found one of them separately with GPT-5.6 Sol, as part of OpenAI’s Patch the Planet program.

On October 26, the U.S. cybersecurity agency CISA added both bugs to its catalog of vulnerabilities that attackers are already using.

PHP’s release notes say there’s no complete workaround and “updating is the only safe choice”. PHP 8.1 and older don’t get a fixed release. For those versions, the PHP team tells people to ask their Linux distribution or support vendor for a patched package, or to move to 8.2 or newer.

A2UI Express

On October 27, Google’s A2UI team announced A2UI Express, a shorter format for the screens AI agents build with A2UI.

A2UI is Google’s open protocol for generative UI (screens an AI agent puts together while you use an app, instead of a developer laying them out in advance). Your app lists the components you trust, like cards and buttons. The agent describes a screen made of those components, which your app draws with its own code.

Until now, the model wrote that description as JSON, with every curly brace and every nested element. The A2UI team says models are slow and make a lot of mistakes when they have to write JSON that follows a complex schema.

With Express, the model writes one line per component, in a style close to Python. A2UI’s agent SDK compiles those lines into the same A2UI JSON as before. You don’t have to change your list of components or the code that draws them.

This is the notification card from the A2UI gallery, written in Express:

surface("gallery-notification-permission")
$/description="Get alerts for order status changes"
$/icon="check"
$/title="Enable notification"
root=Card(main_column)
main_column=Column([icon, title, description, actions], _, "center")
icon=Icon($/icon)
title=Text($/title)
description=Text($/description, "body")
actions=Row([yes_btn, no_btn], "center")
yes_btn_text=Text("Yes")
yes_btn=Button(yes_btn_text, _, Event("accept", {}))
no_btn_text=Text("No")
no_btn=Button(no_btn_text, _, Event("decline", {}))

Each variable name becomes the ID of its component. $/title points at a value in the screen’s data. Event("accept", {}) is the action sent to your server when the user presses Yes.

In Google’s tests, Express needed up to 3 times fewer tokens than JSON for the same screens. The team says that can make them appear up to 3 times faster. It’s now A2UI’s default format.

Express is in the a2ui-agent-sdk package for Python and in @a2ui/agent on npm. A pre-release of the Dart package, a2ui_agent, has it too. In the SDKs, you choose the format with one argument when you set them up, ExpressFormatFactory() for Express.

The post also shows a faster option for screens with a known shape, like a settings page or a checkout. TypeSafe’s decision model Jev returns which of the layouts you defined in advance fits the screen. A smaller Gemini model, gemini-3.5-flash-lite, writes just the text. The post says that option is up to 80 times faster.

The A2UI SDKs don’t support that option yet. Google’s example uses Apparite, an open-source design tool.

OpenAI and Claude on Google Cloud

Google Cloud announced on October 21 that OpenAI’s GPT-6 Astra, GPT-6.1 Sol, and GPT-6 Luna are in its Model Garden (its catalog of AI models from many companies), in private preview for some enterprise customers. The next day, a Claude service that Anthropic runs on Google Cloud became generally available, next to the one Google already runs.

For a team on Google Cloud, that means Gemini and the models from Anthropic and OpenAI under one account and on one bill. A company that has already agreed to spend a set amount with Google Cloud can count what it spends on OpenAI’s models and on Claude toward that amount. Google Cloud says it’s the only one of the big cloud providers that offers all three.

Customers in the preview can call OpenAI’s models through Google Cloud’s APIs, and connect the Codex CLI and the Codex desktop app to Google Cloud, which then runs the models for them. OpenAI says general availability is planned “in the coming weeks”. Both companies say the models are coming soon to Antigravity.

Decision models

OpenAI made its Decisions API generally available on October 22, after two weeks in public beta. It runs in OpenAI’s cloud, unlike Chrome’s Decisions API, which runs on the user’s computer.

The only model is gpt-6-luna, at the same price as in the beta, $0.10 input / $0 output per million tokens. Since the beta, OpenAI added prompt caching, which makes it a lot cheaper to ask more questions about the same long document or image. Cached input costs $0.01 per million tokens.

You can ask up to 400 questions in one request, twice the 200 of the beta, and pass structured data as JSON instead of turning it into text first.

Liquid AI’s d1-ultra is still first on Artificial Analysis’ Decision Index, with 65.25 before rounding.

Baseten released Elephant 9B on October 21 under the name elephant-1. It’s built on top of Alibaba’s Qwen3.5-9B, with the weights on Hugging Face under the MIT license, which lets you use them in any product for free. It scored 64.69 at $8.39 per million tasks, about a quarter of d1-ultra’s $31.80.

Subquadratic put out SubQ Snap 1.1 on October 22, a week after the first version. SubQ Snap 1.1 got 65.00 and costs $0.04 input / $0 output per million tokens. Subquadratic says it takes text and images in requests of up to 384K tokens, against 64K for Jev 1.14 by default.

Liquid AI released LFM3, a family of small open-weight models, on October 27. It includes d1-2B, a decision model for text and pictures that replaces d1-3B. Liquid says d1-2B runs on a laptop and scores 51.1 on the public part of the Decision Index, but Artificial Analysis hasn’t scored it yet.

Want more of these in your Google results?