Commit Graph

1539 Commits

Author SHA1 Message Date
Vincent Koc
0e24d596c0 improve(setup): clarify local provider actions 2026-08-01 00:26:40 +08:00
Vincent Koc
a1026663ae feat(plugins): externalize ComfyUI provider (#116888) 2026-07-31 23:26:51 +08:00
Vincent Koc
e93de36081 feat(plugins): externalize BytePlus provider (#116866) 2026-07-31 22:37:47 +08:00
Vincent Koc
fab2c33cad feat(plugins): externalize Xiaomi provider (#116861) 2026-07-31 22:02:07 +08:00
Vincent Koc
b2b62b2e1e feat(plugins): externalize Volcengine provider (#116854) 2026-07-31 21:28:01 +08:00
Vincent Koc
ba1a6722bb feat(plugins): externalize Vydra provider (#116813) 2026-07-31 20:35:43 +08:00
Vincent Koc
eb55c8ea8f feat(plugins): externalize Voyage embeddings (#116785)
* feat(voyage): externalize embedding provider

* fix(voyage): drop stale bundled description
2026-07-31 19:52:33 +08:00
Vincent Koc
6830820755 feat(plugins): externalize DuckDuckGo search (#116740) 2026-07-31 18:49:07 +08:00
Vincent Koc
a550827dad feat(plugins): externalize Synthetic provider (#116720) 2026-07-31 17:19:43 +08:00
Yuval Dinodia
623a015928 fix(memory-wiki): preserve user edits when rolling back ChatGPT imports (#116517)
* fix(memory-wiki): preserve user edits when rolling back ChatGPT imports

Rollback deleted created pages and overwrote updated pages unconditionally,
destroying content the user added after the import with no recovery copy.
Import runs now record a content hash of each written page after vault
compile, and rollback preserves any page whose current content no longer
matches into the run's recovered directory before deleting or restoring.
Legacy run records without hashes preserve unconditionally.

Fixes #116457

* fix(memory-wiki): move pages aside atomically during rollback

Rollback now renames the live page into the recovery location before
inspecting it, so a concurrent external save cannot land between the
content read and the delete or snapshot restore. Matching pages drop
the moved copy; mismatching pages keep it as the recovery file.

* fix(memory-wiki): make rollback snapshot restore collision-safe

The snapshot restore wrote directly to the page path after the
move-aside, so a page recreated by an editor in that window was
overwritten with no recovery copy. Restore now creates the snapshot
exclusively and on collision moves the recreated page aside and
retries; recovery filenames are uniqued so a second move-aside cannot
clobber an earlier preserved copy.

* fix(memory-wiki): record rollback hashes at write time

* fix(memory-wiki): make ChatGPT rollback retry-safe

* fix(memory-wiki): fence ChatGPT rollback phases

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-31 08:01:52 +00:00
Vincent Koc
fa4cc51a87 feat(plugins): externalize Teams and Zoom meetings (#116682) 2026-07-31 14:10:46 +08:00
Vincent Koc
c892a712e6 feat(plugins): externalize Cohere and Meta providers (#116662)
* feat(plugins): externalize Cohere and Meta providers

* docs(changelog): note provider externalization

* chore: keep changelog release-owned
2026-07-31 12:53:01 +08:00
Kimiyu-openai
43156fe482 fix(codex): add remote WebSocket heartbeat and reconnect (#116135) 2026-07-30 15:38:26 -07:00
Josh Avant
ce67ffb70e feat(agents): add tool-free isolated completion (#114343)
* feat: add isolated pure-inference completion

* fix(google): block ambient system prompt writes

* docs: refresh generated map
2026-07-30 13:24:45 -05:00
Vincent Koc
e96b9d2cd0 improve(ui): verify llama.cpp model setup 2026-07-30 23:41:58 +08:00
Vincent Koc
8a3f5c862b fix(plugin-sdk): ship documented public typings (#116345)
* fix(plugin-sdk): ship documented public typings

* fix(plugin-sdk): refresh public contract artifacts
2026-07-30 18:20:07 +08:00
joshavant
21db50efc7 refactor(whatsapp): keep inbound boundary transport-private 2026-07-29 20:34:55 -05:00
Vincent Koc
f970e5093b refactor(channels): add portable inbound boundary 2026-07-29 20:34:55 -05:00
Vincent Koc
8530edb057 fix(plugins): deliver subagent completion to current requester (#116091)
* fix(plugins): deliver subagent completion to requester

Co-authored-by: ambitioncn <36698505+ambitioncn@users.noreply.github.com>

* test(qa): register current-requester plugin fixture

* fix(plugins): scope requester authority per hook

---------

Co-authored-by: ambitioncn <36698505+ambitioncn@users.noreply.github.com>
2026-07-30 07:06:17 +08:00
Peter Steinberger
b9377f6048 fix(codex): enforce native MCP tool access (#116054)
* fix(codex): enforce native MCP tool access

* chore: remove prerelease changelog entry

* chore: restore changelog to main

* refactor(codex): build MCP server patches from entries
2026-07-29 17:06:49 -04:00
Vincent Koc
83d725761f docs(hooks): clarify inbound claim ownership (#116082)
Refs #109353
2026-07-30 05:02:50 +08:00
Frank Yang
511ecd9dba fix(plugins): expose inbound message id before dispatch (#112359)
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 04:26:28 +08:00
mikasa
d2f2123da5 fix #95351: [Feature]: Generic JSONL line-parsing hook for CliBackendPlugin (native tool-card support beyond claude-stream-json) (#95386)
* feat(plugin-sdk): add CLI backend JSONL parser hook

* fix(test): isolate non-git workspace fixtures

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 03:37:39 +08:00
Stellar鱼
42e23c11e0 feat(plugins): allow per-turn tool narrowing in prompt hooks (#114151)
* feat(plugins): allow per-turn tool narrowing in prompt hooks

* fix(hooks): keep prompt tool policy baseline internal

* fix(test): track active tools in embedded session fixture

* test(agents): preserve active tool fixture state

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 03:28:45 +08:00
Vincent Koc
8a4f891450 docs(hooks): mark pairing hook observation-only (#116055) 2026-07-30 03:27:36 +08:00
Josh Lehman
6beaff450e fix(codex): avoid transcript mirror snapshot churn (#115070) 2026-07-29 11:59:14 -07:00
Naka Masato
68dbf92281 fix(plugins): scope Codex relay with tool matchers (#109603)
* fix(plugins): scope Codex relay matchers

Co-authored-by: Masato Naka <masatonaka1989@gmail.com>

* fix(plugins): reject sparse tool hook matchers

* test(plugins): cover mixed relay matcher scopes

* fix(plugins): fail closed on invalid policy matchers

* test(plugins): prove composed relay policy scope

* fix(plugins): keep matcher scope internal

* fix(plugins): satisfy matcher static checks

* fix(plugins): enforce canonical tool hook matchers

* fix(codex): project native hook matcher aliases

* fix(plugins): scope Codex relay with tool matchers

* chore: keep release changelog maintainer-owned

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 01:39:08 +08:00
Masato Hoshino
458bb58ae5 fix(voice-call): pin Twilio webhook verification to the configured public path (#112800)
* fix(voice-call): pin Twilio webhook verification to the configured public path

buildTwilioVerificationUrl overwrote the configured publicUrl path with the
incoming request path, so behind a path-rewriting reverse proxy the
reconstructed verification URL no longer matched the URL Twilio signed and
valid webhooks were rejected. Use the configured public path (keep the request
query), mirroring the Plivo sibling fixed in #112559. Restores callback-path
binding and adds proxy-prefix accept + local-path reject regression tests.

* fix(voice-call): pin Twilio verification to public URL path

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-30 01:08:38 +08:00
Peter Steinberger
c87e545c88 fix(ui): rename the Memory Palace browser to Memory Wiki and document it (#115954)
* fix(ui): rename the Memory Palace browser to Memory Wiki and document it

* refactor(memory-wiki): drop the old memory-palace module files

* docs: refresh generated docs map

* test(ui): align dream-diary hub-tab assertion with the wiki sub-tab id

* docs: describe memory wiki clustering behavior accurately

* docs(memory-wiki): record the wiki.overview rename decision at the registration site

* test(ui): query the Agents channels hub tab by tab role after the hub-tabs refactor
2026-07-29 12:51:37 -04:00
Peter Steinberger
34e81ca0dc feat(codex): support the openai-api-curated marketplace wire name (#115955) 2026-07-29 11:07:16 -04:00
Vincent Koc
41f118cec3 fix(plugins): forward tool cancellation to hooks (#115817)
* fix(plugins): forward tool cancellation to hooks

* test(plugins): prove hook cancellation propagation
2026-07-29 22:54:01 +08:00
Peter Steinberger
40dafc5c33 refactor: replace context-engine retry proxy with declared params (#115872)
* refactor(context-engine): remove legacy host-key retry proxy

* refactor(context-engine): declare accepted host parameters

* fix(context-engine): preserve engine adapter receivers

* refactor(plugins): tighten context-engine compat record

* refactor(context-engine): inline compat window lookup

* docs(plugins): align context-engine removal diagnostic

* test(context-engine): declare harness proof parameters
2026-07-29 08:37:08 -04:00
stevenlee-oai
a00438a867 fix(codex): restore connected apps for token-authenticated runs (#115075)
* fix(codex): restore connected apps for token-authenticated runs

* fix(codex): keep app inventory protocol types private

* fix(codex): align native runtime with Codex 0.146.0

Co-authored-by: Steven Lee <stevenlee@openai.com>

* fix(codex): clean up latest app-server integration

Co-authored-by: Steven Lee <stevenlee@openai.com>

* fix(codex): keep internal protocol types private

* fix(ci): repair current main Codex landing gates

* fix(ci): format inherited code mode matrix

* fix(codex): reconcile native app-server contracts with main

Prepare a verified GitHub-hosted mainline merge while preserving the reviewed Codex 0.146.0 fixes and canonical OpenAI authentication.

Co-authored-by: Steven Lee <stevenlee@openai.com>

* fix(codex): keep QA evidence in its owning plugin

Resolve the current-main Code Mode test rename without resurrecting the retired core test path.

Co-authored-by: Steven Lee <stevenlee@openai.com>

* fix(codex): enforce canonical OpenAI app-server auth

Reject retired provider aliases without runtime compatibility, direct operators to the doctor migration, and remove the redundant OpenAI API-key predicate.

Co-authored-by: Steven Lee <stevenlee@openai.com>

* chore(codex): reconcile latest main dependency graph

Preserve current main dependency changes while preparing the original Codex PR for an ancestry-preserving signed mainline merge.

Co-authored-by: Steven Lee <stevenlee@openai.com>

* fix(codex): unify bundled Codex 0.146 runtimes

Keep the ACP adapter on the same 0.146.0 Codex release as the managed runtime, remove obsolete 0.145.0 platform artifacts and unused semver compatibility, and preserve the latest main dependency upgrades.

Co-authored-by: Steven Lee <stevenlee@openai.com>

---------

Co-authored-by: Peter Steinberger <peter@steipete.me>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-29 06:21:25 -04:00
Hannes Rudolph
6dc55fa65e fix(plugins): recover user turns with scoped reply hooks (#114836)
Allow before_agent_reply plugins to declare host-enforced trigger eligibility so scheduled-only hooks do not block interrupted user-turn recovery. Keep omitted and malformed scopes fail-closed, scope both memory-core maintenance hooks, and cover three runner reload cycles through the public registration contract.

Refs: #111442

Source: #114836

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-29 17:22:16 +08:00
Peter Steinberger
e8524a5839 feat: add Fish Audio S2.1 and local MLX speech (#115790)
* feat: add Fish Audio speech support

* chore: remove unused speech exports

* chore: keep Fish API constant private

* test: remove stale code mode import

* style: use bracket access for Fish voice ids

* test: restore QA evidence validator import
2026-07-29 05:15:33 -04:00
Vincent Koc
80707db7ab fix(plugins): bound hook execution and retire stale registrations (#115695)
* fix(plugins): bound hooks and own legacy registrations

* docs(hooks): clarify internal handler ownership

* fix(cli): retain message hook shutdown deadline
2026-07-29 16:44:05 +08:00
Vincent Koc
bf91a5786c fix(plugins): enforce hook security invariants (#115701) 2026-07-29 16:10:34 +08:00
Vincent Koc
14940edf15 feat(skills): add Skill Workshop lifecycle hooks (#115606)
* feat(skills): add lifecycle hook contracts

* feat(plugins): expose skill hook contracts

* feat(plugins): identify skill evaluators

* feat(skills): persist proposal evaluation lifecycle

* feat(skills): add agent evaluation action

* feat(skills): emit committed skill lifecycle changes

* feat(gateway): expose skill proposal evaluation lifecycle

* feat(ui): add Skill Workshop evaluations

* fix(skills): bind lifecycle state to proposal revisions

* fix(skills): preserve lifecycle events without artifacts

* feat(cli): evaluate skill proposals

* fix(ui): bind evaluations to proposal revisions

* docs(skills): document lifecycle hook primitives

* chore(plugin-sdk): refresh skill hook surface

* fix(skills): harden proposal evaluator execution

* fix(plugins): isolate skill evaluator inputs

* fix(cli): align skill lifecycle deadlines

* fix(skills): preserve evaluation replay invariants

* test(ui): capture Skill Workshop evaluation proof

* fix(skills): bind apply to evaluated target tree

* fix(skills): preserve evaluation contract edges

* fix(skills): bound evaluation event storage

* chore(skills): keep lifecycle helpers internal

* refactor(skills): isolate evaluation persistence

* fix(skills): satisfy lifecycle validation gates

* chore(protocol): refresh Skill Workshop clients

* docs: refresh Skill Workshop map

* chore: keep release notes in PR metadata

* docs: refresh merged docs map

* fix(ci): type Code Mode catch errors

* fix(skills): freeze lifecycle observation payloads

* fix(protocol): keep proposal inspect backward-decodable

* fix(skills): enforce final evaluator bundle limits

* fix(skills): preserve lifecycle caller attribution

* chore: drop subsumed Code Mode formatting

* test(plugins): adapt lifecycle hook mocks
2026-07-29 15:49:44 +08:00
Peter Steinberger
a7cecc85d3 fix(codex): safely deliver remote workspace files and images (#115668)
* fix(codex): safely deliver remote workspace files and images

* chore(codex): keep release notes in pull request

* style(scripts): repair current main formatting gate

* refactor(codex): remove unused remote filesystem RPC types

* docs: refresh generated documentation map

* test(codex): type remote workspace reader mock

* fix(ci): preserve plugin test ownership boundary

* refactor(codex): split remote transfer protocol and projection types
2026-07-29 03:37:50 -04:00
Peter Steinberger
032defb172 fix(nodes): cancel paired local inference when callers disconnect (#115624) 2026-07-29 02:00:22 -04:00
Kevin Lin
310396f1e1 fix(codex): enable configured apps in service sessions (#115433)
* fix(codex): attest configured plugin apps before turns

* fix(codex): tighten plugin thread config

* fix(codex): expose account app admission wrapper
2026-07-28 22:39:20 -07:00
joshavant
a6d58f0e6d fix(codex): attest safe Node network options 2026-07-28 23:22:52 -05:00
ooiuuii
8ffc567075 fix(plugins): keep bulk updates on the beta channel (#115083)
* fix(plugins): preserve beta channel on bulk update

* docs(plugins): document beta bulk update fallback

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-07-29 12:04:38 +08:00
Shakker
7620475a2f docs: explain native subagent handoff 2026-07-29 02:22:09 +01:00
Peter Steinberger
f78ba09120 feat(talk): support GPT-Live realtime voice over ChatGPT OAuth (#115226)
* feat(gateway): share the canonical browser-origin policy with plugins

Export resolveAcceptedBrowserOrigin through openclaw/plugin-sdk/webhook-request-guards
so browser-facing plugin routes reuse the Gateway's real origin contract instead of a
narrow allowedOrigins array check. Private LAN/Tailnet Control UI loads and the
Host-header fallback were previously rejected with 403 by plugin offer routes while the
Control UI itself worked.

Moves the loopback/forwarded-header helpers to net.ts (re-exported from auth.ts) so the
guard can delegate without importing gateway auth, and migrates the Codex realtime
broker onto the shared seam.

* feat(talk): let providers own agent delegation for realtime voice

Adds an optional runAgentConsult callback to the browser-session create request and
injects the existing embedded consult runtime from talk-client, bound to the same agent
and session key the GA tool path uses. Providers whose realtime protocol delegates work
through their own control channel (rather than GA function calls) can now reach the
OpenClaw agent without a client round-trip.

Threads the effective per-session model into browser-session capability resolution so a
request-level model override selects the right capability set, and propagates a caller
abort signal into consultRealtimeVoiceAgent so a superseded delegation stops its run.

* feat(openai): support GPT-Live realtime voice over ChatGPT OAuth

Implements OpenAI's quicksilver/frameless session natively for Talk browser sessions.
The Gateway creates the WebRTC call (multipart sdp+session to https://api.openai.com/v1/live)
and owns the sideband control socket, so the browser never holds upstream credentials;
delegation.created events run through the OpenClaw agent and stream back as speakable
context appends.

Verified end-to-end on 2026-07-28 against a ChatGPT Pro OAuth profile: call create 201
with an rtc_* id and answer SDP, sideband session.started, session.close teardown.
ChatGPT OAuth is preferred over a Platform API key because /v1/live access for platform
keys is waitlist-gated; the legacy chatgpt.com backend route returns 403 for every model
and protocol version and is not used.

Accepted models are gpt-live-1-codex and gpt-live-1-boulder-alpha; the voice allowlist is
the ten values the route actually accepts, since an invalid voice is rejected at call
creation and cannot be repaired afterwards (session.update reports immutable_field_update).

* docs: document GPT-Live Talk support and its route gotchas

Records the working route and auth, the accepted models and voices, the browser-only
scope, and the two traps that cost the most time: the chatgpt.com backend route returns
403 Voice session access denied for every model, and that same 403 is also what an
invalid voice returns, so it must not be read as an account entitlement block.

* fix(openai): resolve GPT-Live CI failures

* refactor(openai): own zod runtime dependency

* fix(openai): satisfy lint and live-shard gates for GPT-Live

Types the retry-delay finish callback as Error so the rejection reason is provably an
Error at the call site; the abort path already normalized a non-Error AbortSignal reason,
but the unknown parameter type hid that from static analysis.

Registers the new GPT-Live live test in the native-live-extensions-openai shard
expectation. The shard selector already picked the file up from the real tree; only the
hardcoded list in the tooling test lagged.

* fix(openai): clean up post-rebase capability resolver

* fix(openai): preserve GPT-Live delegation fragments

* fix(openai): close GPT-Live sideband handoff race

* fix(openai): accept UUID GPT-Live call ids

* style: apply oxfmt to GPT-Live sources and Talk docs

* style: format Talk docs after rebase

* fix(openai): keep GPT-Live transcript context across ignored delegations
2026-07-28 15:05:55 -04:00
Peter Steinberger
e89ff13494 fix(nostr): report unavailable ingress when queue open fails (#115313)
* fix(nostr): surface durable ingress startup failures

* chore: keep changelog release-owned
2026-07-28 13:34:23 -04:00
Peter Steinberger
695db84cd1 feat(plugins): match shared models across vendor-namespaced catalog ids (#115210)
Aggregators republish first-party models under a namespaced id and varying
case, so the shared-model check could not group novita/moonshotai/kimi-k3 with
moonshot/kimi-k3. Matching now ignores one leading namespace segment and case,
which catches that whole class automatically instead of needing an
upstreamModel marker per row.

Declares the tier on the 18 rows this surfaces across baseten, deepinfra, gmi,
novita, nvidia, and together. All are "capable", matching what the runtime
already applied for an absent flag, so behavior is unchanged.
2026-07-28 10:22:23 -04:00
Peter Steinberger
fe9893d41c refactor(agents): resolve code-mode vs tool-search once for every harness (#115189)
* refactor(agents): share one tool-surface resolver across runner and harness

The code-mode vs tool-search gate decision and the three-way catalog
application were duplicated across the embedded runner and the native
harness bridge, and had already drifted: the harness copy was missing the
skillWorkshopProposalOnly condition and its params object had no field to
express it.

Both surfaces now consume resolveAgentToolSurfacePlan and
applyAgentToolSurfaceCatalog, so the gates and the catalog branch exist
once. Both gate booleans derive from a single shared toolsAvailable
intermediate.

Behavior change: the harness path now honors skillWorkshopProposalOnly.
Proposal-only skill-workshop runs are deliberately narrow single-tool runs,
so code-mode indirection and tool-search catalogs are pure overhead — a
harness-independent reason. Both callers currently pin
agentHarnessRuntimeOverride "openclaw", so this closes a latent fail-open
rather than fixing a live bug.

* fix(agents): let the shared catalog params carry a config-less run

resolveAgentToolSearchRuntimeConfig returns OpenClawConfig | undefined, so
requiring a non-null toolSearchRuntimeConfig broke tsgo:core at both call
sites. Keep the key required so it cannot be silently omitted, but let the
value be undefined as the pre-refactor code already allowed.

* fix(agents): keep the tool-surface module free of dead exports

Importing isCodeModeEngagedForModel and applyToolSchemaDirectoryCatalog from
their defining modules left the code-mode.ts and tool-search.ts re-exports with
no production consumer, which knip rejects. Go back through the barrels, which
is also what both call sites did before this refactor.

The two params types were exported only for the test, so knip's production scan
saw them as dead. Keep them module-local and derive the type in the test.
2026-07-28 09:16:35 -04:00
Peter Steinberger
99ec30b44b feat(plugins): catch code-mode drift between catalogs shipping the same model (#115183)
* feat(plugins): catch code-mode drift between catalogs sharing one model

Adds a contract test that groups bundled catalog rows by shared upstream
model and requires every row in a group to declare compat.codeMode once any
sibling does. Rows sharing a model id group automatically; rows under
different ids opt in with the new manifest-only `upstreamModel` marker.

Moves the kimi catalog into its manifest so the scan can see it, and records
the tier reseller catalogs were silently missing as explicit "capable".

* docs: regenerate docs map for the shared-model code-mode section
2026-07-28 08:52:21 -04:00
Peter Steinberger
0d7fb8eb39 refactor(fs): adopt fs-safe 0.5 core primitives (#113705)
* refactor(fs): unify exclusive file publication

* fix(fs): fence stale lock reclamation

* refactor(fs): bound wiki scans and secret reads

* chore(fs): finalize fs-safe 0.5 compatibility

* fix(fs): preserve publication ownership and legacy mode

* fix(fs): fail closed on unverifiable lock owners

* fix(fs): preserve concurrent backup publications

* refactor(fs): preserve ambiguous backup outputs

* fix(fs): preserve mixed-version lock coordination

* refactor(file-transfer): adopt fs-safe archive extraction

* refactor(fs): add bounded walk and secret seams

* refactor(auth): replace proper-lockfile with fs-safe

* fix(fs): honor Windows mode override casing

* refactor(snapshot): adopt fs-safe publication

* refactor(memory-wiki): adopt prunable root walks

* refactor(fleet): adopt bounded archive restore

* fix(fs): preserve post-publication ownership receipts

* refactor(fs): harvest final fs-safe primitives

* style(fs): clean harvest lint

* chore(plugin-sdk): refresh move helper API baseline

* refactor(snapshot): adopt native Windows ACL facts

* refactor(fs): adopt hardened atomic outputs

* fix(fs): scope lock reentrancy to logical owners

* chore(config): lower env var count budget

* fix(deps): adopt published fs-safe 0.5.0

* fix(ci): align SDK surface ratchets

* fix(ci): regenerate SDK API baseline after rebase

* fix(fs): preserve owner-scoped file lock nesting

* fix(ci): refresh SDK API baseline for file locks

* fix(fs): separate SQLite and file lock reentrancy

* fix(imessage): bound pinned attachment reads

* fix(agents): narrow session-key lock options

* fix(fs): preserve fs-safe 0.5 compatibility contracts

* fix(windows): retain private SQLite directory owner

* refactor(sqlite): centralize exclusive coordinator

* refactor(snapshot): isolate Windows ACL policy

* fix(windows): retain snapshot ACL inspector

* chore(config): realign env budget after rebase

* test(agents): accept canonical sandbox escape error

* docs(changelog): defer fs-safe release note
2026-07-28 03:41:47 -04:00