Vai al contenuto

Blog

Releasev0.48.1

v0.48.1

Questa è la nota di release così com'è stata pubblicata, non una sua riscrittura. Le note di release sono pubblicate nella lingua in cui sono state scritte.

An audit of the shipped 0.48.0, run against the running app rather than the source. Almost all of it is one defect wearing different clothes: something existed, had tests, and had never run.

⚠️ Read this one before upgrading

CHIMERA_APPROVAL_MODE=allow now does something on the desktop app and on chimera serve. It reached solve and crew and no other surface, so an owner who set it still got a refusal from the two surfaces most people use. If that variable has been sitting in your .env since before this release, the agent will stop refusing dangerous tools after it reads untrusted content — which is what the setting always said it would do, and did not.

The number that justifies wiring it, from bench/injection, which carried a pre-registration from 2026-08-14 and had never been run:

no approver     blocks 85.7% of attacks · refuses 50.0% of honest work · FAIL
with approver   blocks 85.7% of attacks · refuses  0.0% of honest work · PASS

The refused work is ordinary — fix the file the issue names, apply the upgrade the docs describe — and the control (tasks that read the repository first) is refused 0%, which isolates the cause to the external door. The 85.7% that does not move is not a free lunch: the bench hands the approver to the legitimate corpus only, modelling a person approving work they asked for. A standing allow approves whatever an injected page asks for too. The default does not move, and ask is deliberately not wired on a server — with nobody at a console it would wait fifteen minutes inside an HTTP request.

Four ways to run a task, and one box to type it in

The Work screen had four forms asking for the same sentence — a run, a lifecycle, a fan-out, and the crew buried two clicks inside the fan-out. So the choice of how came before the task existed, and trying the second way meant typing it a second time. Which is why nobody tried the second way.

They are one screen now, with four buttons for what happens to what you typed, and the tabs go from five to four. The task and the check travel between modes because they are the same thing in each; attempts, roles and worker slots stay inside the mode that means them.

Three things a merge like this does quietly, and this one does not:

  • The fan-out has no check to send — its workers are mounted tool-free — so the field is hidden and, when something is already typed in it, the screen says the text is kept and not sent. A field that vanishes with text in it looks like the text went somewhere.
  • The mode strip locks while a run is live, with the reason on screen, because switching would unmount the running mode and kill its stream while the tokens keep being spent. New on paper and nothing in practice: leaving by switching tabs already did exactly that, in silence.
  • The fallback note now selects the crew instead of only recommending it. It has always been able to say this task writes files, that goes to a crew, and saying it was all it could do.

Fixed

  • An empty variable stopped the app from starting. CHIMERA_GUARD_CHAT= in a .env and nothing runs — all twenty-six boolean settings, with a pydantic traceback naming a type rather than the line to fix. VAR= is how a line gets turned off without being deleted, and this repository's own .env ships with OPENROUTER_API_KEY= empty. An empty value now reads as unset. The key is dropped rather than coerced to False, which would have silently switched off every setting that defaults on — a security posture among them.
  • The cost meter went quiet on exactly the expensive models. Nine of the fifteen shipped models reported an unknown cost, claude-opus-5 ($5/$25 per 1M) and gpt-5.5 ($5/$30) among them, because register_catalog_prices() had five tests and no caller. Nobody noticed because the default model is one of the six that resolved: the meter read correctly until somebody chose an expensive model, and went quiet at the moment the number mattered.
  • The focus ring the button never adopted. Twenty-one components import the shared ring; the Button was not one of them, and the two had drifted. The test meant to prevent this asserted total >= 1 — a floor, on a rule whose name promises a ceiling. It was green at eight.
  • Two publish gates that could not run where they run. The wheel scanner died on ModuleNotFoundError: rich before reading a byte, and once fixed, stopped the release on twenty-nine fake keys inside tests whose subject is what a key looks like.

Added

  • CHIMERA_DEFER_TOOLS — twenty-two tool schemas go out on every step of every turn, ~3,224 tokens before the user types. With this on, the core stays declared and the rest sits behind tool_listtool_describetool_call.

    Off by default, and bench/tool_defer is why. Sixty paired executions: cost fell 26% per task completed, and the agent reached the proxy in 23 of 30 runs with no case of failing to find a tool and giving up. But completion came out A 52% × B 35% with four discordances all one way — McNemar p = 0.125, inconclusive, exactly as the pre-registration said a difference that size would be. And the reason it cannot answer is the bench's own fault: four of its ten tasks fail in both arms.

  • The command reference gate fires on the pull request, not on the deploy. "Every command is listed" was already checked — on the documentation site, which meant it could only run after a release.

Measured, and left alone

Two security benches carried pre-registrations and had never been run. Both are committed as artefacts under bench/*/results/, and bench/memory_poison fails its own gate: 25% of honest memory destroyed, the casualties being text that quotes an attack in order to explain it. Its own output names the cause: a pattern matcher on content cannot tell the quote from the command. No threshold was moved to make that number look better.


Full notes: CHANGELOG.md

Leggi la release su GitHub