* fix(agents): stop apply_patch from silently overwriting existing files
An "*** Add File:" hunk wrote its target unconditionally. When the path
already existed, apply_patch replaced the entire file, returned Success,
and listed the path under "added", so neither the model nor the UI got
any signal that existing content had been destroyed. The "*** Move to:"
destination of an update hunk had the same gap and reported the clobbered
path as merely modified.
The add and move-to branches now check the destination through the patch
file ops before writing and fail closed when it exists. Routing the check
through fileOps keeps it correct on all three backends (workspace-scoped
fs-safe root, raw fs, sandbox bridge). The check runs per hunk in patch
order, so deleting a path earlier in the same patch and recreating it
still works.
* fix(agents): make apply_patch destination creation atomic
The previous guard checked that an add or move-to destination was absent
and then wrote it. A competing writer could create the path in that gap,
after which the write still replaced it, so the no-clobber guarantee did
not hold under contention.
Destination creation now goes through a single exclusive create-if-absent
operation on every patch backend: Root.create for the workspace-scoped
default, an O_EXCL write for the raw filesystem, and a new pinned create
operation in the sandbox mutation helper that opens the target with
O_CREAT|O_EXCL and reports a reserved exit code when it already exists.
PatchFileOps drops its separate existence check.
Resolving the host ops behind an early return removes the repeated
workspaceOnly branch inside each operation and the optional-call dance
that let a missing root silently skip a write.
* fix(agents): complete atomic apply-patch creation
* fix(agents): preserve raced create replacements
* fix(agents): handle fs-safe patch collisions
* fix(agents): publish sandbox creates atomically
* test(agents): cover exclusive create provenance rollback
* fix(agents): use typed exclusive-create signal
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* fix(config): materialize snapshot mode with the same defaults as load
* test(config): prove snapshot-injected defaults stay out of persisted config
* test(cli): keep unknown-command process test hermetic
---------
Co-authored-by: Kevin Lin <kevin@dendron.so>
* feat(gateway): manage audio and video attachments
* feat(gateway): preserve generated media metadata
* fix(gateway): align seeded managed media
* fix(gateway): scope pending media trust by URL
* fix(gateway): split managed media by trust
* fix(gateway): require terminal media trust unanimity
* fix(gateway): align managed media metadata types
* fix(gateway): refresh managed media contracts
* chore(ci): model managed media test seams
* test(sessions): expect canonical media kinds
Route pattern, dependency, and active conditional schemas through the real plugin config validator while keeping standalone conditional annotations on the empty-config path.
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(cli-runner): scope bundle-MCP cleanup to the run's session, not the process-wide loopback server
On run end, runCliAgentInternal handled cleanupBundleMcpOnRunEnd by calling
closeMcpLoopbackServer(), which tears down the process-wide MCP loopback HTTP
server for the whole gateway. Any concurrent CLI turn or restart-recovered live
session that already baked that loopback port into its --mcp-config is left
pinned to a dead port ("Unable to connect"), while the gateway still reports the
session as recovered. This is the same hazard the embedded-runner (run-loop.ts)
and CLI dispatch (cli-backend-dispatch.ts) paths already avoid by retiring only
session-scoped MCP runtimes.
Retire only this run's session-scoped MCP runtime here too (by session key, with
a session-id fallback), leaving the shared loopback server up for other sessions.
Every CLI spawn/respawn already re-derives the current loopback port and rewrites
mcp.json via prepareCliRunContext, so removing this teardown keeps recovered
sessions on a live transport instead of stranding them.
Fixes#98435
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MMPjCgbgHTiB8X3R9XACPW
* fix(cli): preserve rebound MCP session owners
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
The spawned agent child process in createAcpClient had no error
listener. If the agent binary failed to start, the error event
would be unhandled and could crash the process.
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* 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>
Fixes#106910.
Preserve the contributor design from #107000 while updating both the normal and current compaction owner paths.
Co-authored-by: Sebastien Tardif <sebtardif@ncf.ca>
* fix(sandbox): safely repair sandbox workspace state
Fixes#111661. Repair active agent, shared, session, and global sandbox workspace state through the existing canonical SQLite registry without importing inactive or unrelated agent state.
Preserves and builds on the original sandbox doctor migration and regression from #111812.
Co-authored-by: TianT1209 <55179364+TianT1209@users.noreply.github.com>
* fix(sandbox): isolate doctor sandbox state by profile
Resolve exact sandbox scope ownership from the state directory requested by doctor, not ambient process state, and cover cross-profile SQLite registry isolation.
Co-authored-by: TianT1209 <55179364+TianT1209@users.noreply.github.com>
* test(sandbox): preserve typed workspace ownership proof
Keep exact inactive and active sandbox fixture paths non-optional under the repository core-test typecheck.
Co-authored-by: TianT1209 <55179364+TianT1209@users.noreply.github.com>
* fix(sandbox): ignore stale non-session workspace scopes
Validate canonical registered session ownership before Doctor migrates sandbox workspace state; preserve exact profile isolation and leave the existing registry untouched.
Co-authored-by: TianT1209 <55179364+TianT1209@users.noreply.github.com>
* fix(doctor): derive sandbox ownership from durable sessions
Read the existing agent-owned SQLite session store without opening writable handles. Repair pruned, global and unscoped sandbox workspaces and resolve omitted sandbox roots from the selected state profile. Retire the transient runtime registry reader.
Co-authored-by: TianT1209 <55179364+TianT1209@users.noreply.github.com>
* test(doctor): derive overlap workspace from agent owner
Honor current main workspace-qualified sandbox scope contract when proving non-default agent ownership in hosted CI.
Co-authored-by: TianT1209 <55179364+TianT1209@users.noreply.github.com>
---------
Co-authored-by: TianT1209 <55179364+TianT1209@users.noreply.github.com>
* docs(agents): standardize canonical record guards
* refactor(model-catalog): use canonical record guard
* refactor(scripts): use canonical record guard
* refactor(ui): use canonical record guard
* refactor(codex): use canonical record guard
* refactor(agents): use canonical record guard
* refactor(sessions): use canonical record guard
* refactor(doctor): use canonical record guard
* refactor(infra): use canonical record guard
Keep successful and failed setup/channel wizard exits inside their owning session. Preserve the shared Gateway and existing protocol; prove both flows with authenticated WebSocket E2E.
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: TheAngryPit <16145902+TheAngryPit@users.noreply.github.com>
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>
Preserve the authoritative inbound group origin for private Mattermost channels without changing public channels, direct messages, thread keys, or the native channel delivery target. Prove both Bot API channel types over real HTTP, gateway discovery, and SQLite-backed outbound persistence.
Credit the original group-origin observation in #95669.
Co-authored-by: hansraj <hansraj136@gmail.com>
Fixes#115524 by keeping path canonicalization scoped to each manifest and persisted registry build.
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Make the subprocess timeout opt-in so long-running setup steps (brew
install, service restart, sudo writes) keep their unbounded wait, and
apply a 15s SIGKILL-backed deadline only to the fast brew --prefix probe
so a signal-resistant hung shim cannot block dns setup.
Also fix the regression test on Linux CI: stub process.platform via
withMockedPlatform (the action does not consult os.platform()) and point
the mocked brew prefix at a real temp dir so un-mocked fs writes succeed
without sudo. Add focused coverage that non-probe subprocesses stay
unbounded.
(cherry picked from commit 469ae1db40)
Co-authored-by: thomas.szbay <thomas.szbay@example.com>
Qualify non-shared sandbox identities by resolved workspace while preserving shared runtime names. Existing non-shared runtimes reset once under the new identity.
Related: #51363
Co-authored-by: Tayoun <39609208+tayoun@users.noreply.github.com>