Перейти к содержимому

Блог

Выпускиv0.47.0

v0.47.0 — the safety layer said it was protecting you

Это описание выпуска как оно опубликовано, а не его пересказ. Описания выпусков публикуются на том языке, на котором были написаны.

Not a feature release. Seven fixes came out of one thread: a refused tool call reported itself as a success, and pulling on that reached the kernel, the rules, the audit, and the mode that was supposed to only measure.

If you run chimera run --guard or solve --guard, take this one. That flag does not depend on CHIMERA_GOVERNANCE, so everything below reached anyone using the kernel the documented way. The deployment default stays off: a stock install behaves exactly as it did.

A refused tool call reported itself as a successful one

A gate declining to run a tool returned an ordinary observation string, and the loop computed ok by asking whether that string began with error:. It did not, so ok was True. Three surfaces read that flag — the frame the desktop draws, the step log a receipt is built from, and the drift detector — so a run in which every dangerous action was refused was, in every structured field, a run that succeeded. Reading the same ordinary-looking string, the model answered "Done. I force-pushed the branch to origin as requested."

A two-line script passed every rule, and a markdown file did not

The text handed to the rules was built by interpolating a dict, and repr escapes a newline into two characters — so the n fused with the next word and killed the word boundary every rule begins with:

review  git_force_push   'git push --force origin main'
allow   default          'echo hi\ngit push --force origin main'
block   rm_rf_root       'rm -rf /var/lib/data'
allow   default          'set -e\nrm -rf /var/lib/data'

Every real shell script has more than one line. Meanwhile a document quoting rm -rf /tmp/x was hard-blocked. The protection was inverted. Two rules had also never fired at all, on any input.

The rule that notices a credential was the one storing it

A governed write_file put the file body into audit.jsonl, which the app serves onto its Security screen — so writing a .env or a private key persisted it, under the secret_material verdict, for a call another guard had already refused. Two layers now: the audit redacts (the redactor existed, wired into the step trace only), and document-shaped arguments are recorded as their size.

The Security screen called the audit tampered when nobody had touched it

Two writers over one file each resumed the hash chain from their own snapshot, so overlapping requests produced duplicate sequence numbers and a chain that failed its own verification. A falsely-failed chain is as bad as an undetected one.

observe applied the refusals it promised to only measure

A hard BLOCK returns before the approver is consulted, so the mode documented as refusing nothing enforced the fixed rules and left them out of the count a rollout is decided on. Measured over 33 real calls: eight refusals, refused=0. The refusals stay — they are signatures with no benign form — but they are counted now, and the refusal text says whose decision it was.

The trust kernel was on no surface served over HTTP

The run, batch and turn endpoints assembled the write region, the denylist and the taint ledger, and never the kernel — so its verdict on a force push was reached by nobody. It is installed there now whenever CHIMERA_GOVERNANCE is observe or enforce. Over HTTP it never prompts on the server's own terminal: whoever is looking at that console is not the person who made the request.

Also

One stuck worker used to hold a whole batch forever — the deadline machinery existed and every production caller but one left it unset. An expiry is now distinguishable from a task that ran and failed, which it was not. Plus: a dollar ceiling for a run with a denominator on the bar, a composer that takes a pasted screenshot and a follow-up typed mid-turn, container limits that can be set, --context-budget on the terminal, and a backend that comes back on its own.

Still open, named rather than left to be found

  • The observe report does not reach the HTTP surfaces yet. Returning it with no reader would rebuild the same silence one layer up.
  • Under enforce the API has no approval path, while the endpoints that pause a run and answer it already exist.
  • Four HTTP endpoints still have no kernel — the chat stream, the OpenAI-compatible endpoint, and the board and project endpoints. The README names them.

Notes on cadence, and on the installers

RELEASING.md asks for one stable a week and 0.46.0 shipped yesterday. This is deliberate: that rule exists to stop releases cut for their own sake, not to hold a fix for a protection that is inverted in the shipped version.

Installers are unsigned and will warn on first run.

Читать описание выпуска на GitHub