## What changed
- Add the opt-in `executed_tool_call_metadata` feature to record model-attempted direct and code-mode tool calls.
- Attach recorded names and arguments to the matching tool output in the next Responses request, preserving the metadata across sampling retries.
- Bound pending calls and argument sizes, and emit truncation metadata when limits are exceeded.
## Testing
- Cover disabled-by-default behavior, namespaced and nested calls, blocked or failed attempts, retry handling, and recorder limits.
GitOrigin-RevId: 5ce917b73e797b0f6904d46477b9d2cf8ea71bf2
## What changed
Add integration coverage for managed network requests that verifies:
- Guardian allow and deny decisions apply only to the triggering request.
- A decision for a remote environment does not carry over to a local one.
- A user-granted remote session approval remains active after Guardian-reviewed requests.
- Guardian assessments receive the exact network action and execution environment for each request.
GitOrigin-RevId: 6701074c6d60b9f28a6d47ebaf910bb1e9f2fa07
## What changed
Add integration coverage for `apply_patch` with unified exec workspace roots. The test verifies that a normal file can be added while writes under existing `.git`, `.agents`, and `.codex` directories are rejected and do not create files.
GitOrigin-RevId: 21ad5ce7fb06e7c47b4086c1439f12d52d9235de
## What changed
Return telemetry tags directly from `CoreToolRuntime::telemetry_tags` instead of
wrapping them in a future, and update the MCP runtime and tool registry call site
accordingly.
GitOrigin-RevId: 54e03972fe23c0e644c68c73af504dba0871be8e
## What changed
- Force an online model-catalog refresh and verify that the mock server receives it.
- Allow the catalog mock to handle repeated requests.
- Bound the catalog refresh and session shutdown with timeouts, and explicitly wait for shutdown before completing the test.
GitOrigin-RevId: 503b52fd296928757b982abc053c74ed36700ff0
## What changed
- Replace fixed delays with explicit signals that pause the sideband connection after its HTTP handshake request begins.
- Release the handshake after closing the realtime conversation and verify that the connection ends before the handshake completes.
- Shut down the test session while rejecting stale realtime errors or duplicate close events from the canceled sideband task.
GitOrigin-RevId: 37072842b973fff41ec47235ceb9cfe3cf1a5a37
## What changed
- Seed approval scenarios with the bundled model catalog so their model metadata is deterministic.
- Make the patch approval helper surface unexpected exec approvals, errors, aborts, and shutdowns immediately instead of waiting for its timeout.
GitOrigin-RevId: b5ec88494ecaf571a480b4142300eb5f3f98def9
## What changed
Update the code mode yield and termination integration test to generate a
bounded output backlog, then wait on a file-backed gate until the session is
terminated. Remove the timeout that previously guarded submission of the
infinite-loop workload.
GitOrigin-RevId: dd48307f18ab12bfbf02dc26b0f3715f073402a7
## What changed
- Run the strict auto-review enabled and disabled scenarios as separate test cases on a two-thread Tokio runtime.
- Explicitly shut down each Codex instance after verifying that the approved folder grant allows the later `apply_patch` call.
GitOrigin-RevId: cbbf47d834c4a9adcf181b97b8aa72b5f0a513e2
## What changed
Build the `apply_patch` filesystem sandbox context from the executor's canonical permission profile instead of the execution attempt's materialized profile. Continue merging any additional permissions requested by the patch while keeping workspace roots scoped separately to the attempt.
## Testing
- Update the sandbox-context test to verify that executor `workspace-write` permissions are preserved when attempt workspace roots and additional file permissions are present.
GitOrigin-RevId: 2a9a8c2e1b1945e300283c400d0f1e573225a553
## What changed
- Track the first registered tool for each normalized code-mode identifier and use that tool consistently for dispatch metadata and model-facing code-mode declarations.
- Skip duplicate normalized names when building the code-mode executor while preserving shadowed tools in the registry and direct tool exposure where applicable.
- Cover collisions across dynamic and namespaced tools, direct and deferred exposure, code-mode-only operation, and Responses Lite metadata.
GitOrigin-RevId: a4acb57ce44e7de1398981b22af4b87e2a35870f
## What changed
- Retain bounded, non-completion agent messages in remote v2 compaction history so delegated tasks remain available on follow-up turns.
- Account for encrypted agent-message content when estimating token usage and place restored initial context before the latest real user or agent message.
- Exclude child completion messages from retained follow-up history and strip inherited parent agent messages when forking a child.
## Testing
- Extend compaction, history-estimation, and agent-fork tests to cover encrypted delegated tasks, child completions, context ordering, and fork sanitization.
GitOrigin-RevId: ba4392e9cfdf4ecbcdc9c7d8581d58a8d2d78260
## Why
External MCP, extension, and dynamic tools can collide with host-owned tool
names. In particular, a dynamic `tool_search` definition must not replace the
host implementation used to discover and route deferred tools.
## What changed
- Build each turn's tools through a single ordered `ToolRegistry` that retains
the first runtime registered for a name.
- Treat duplicate external tools as skippable collisions while preserving
strict duplicate checks for trusted host tools.
- Reserve host-owned code-mode and `tool_search` runtimes before producing the
model-visible tool list.
- Base hosted web-search fallback behavior on the extension runtime that
actually won registration.
## Testing
- Cover ordered registry mutation and duplicate handling.
- Verify a client-provided `tool_search` cannot shadow the host tool.
- Verify hosted web-search fallback follows the registered browser runtime.
GitOrigin-RevId: acebe360de8ec69ad7da2f684cc2542cbf18a984
## Why
Executor capability discovery can traverse plugin and skill roots, including
symlinks. Under restricted filesystem permissions, discovery must not expose
files outside the permitted paths.
## What changed
- Pass each environment's filesystem sandbox context through capability root
discovery and apply it to metadata, directory walks, and file reads.
- Enable discovery for restricted sessions so permitted executor skills remain
available while inaccessible roots and symlink targets are omitted.
- Key discovery caches by sandbox context and reject sandboxed discovery on
executors that do not advertise support for it.
- Split requests with more than 128 roots into supported-size batches.
## Testing
- Cover permitted and denied external symlink targets.
- Verify restricted skill listing excludes inaccessible skills.
- Verify cache separation across permission contexts and discovery of 129 roots.
GitOrigin-RevId: 44d16468ca003403bdb8b71a04ae8c9ff94ed494
## Why
Executor-backed skill resources must honor the active filesystem permission profile instead of reading outside its allowed roots.
## What changed
- Propagate each environment's filesystem sandbox context into `skills.read` calls.
- Apply turn-scoped permission grants when reading executor skill resources.
- Fail closed when no matching sandbox context exists or a restricted Windows read cannot be sandboxed.
- Preserve the existing resource size limit for both sandboxed and streamed reads.
## Testing
- Cover reads within permitted roots and reads that succeed after a permission grant.
- Verify denied references do not expose their contents and disabled Windows sandboxing is rejected.
GitOrigin-RevId: 5cc679b9385b0621665ff20cf5848863cc6396a4
## What changed
- Add an optional `wait_until_ready` hook to `CoreToolRuntime` and invoke it
before acquiring the tool execution gate.
- Move MCP refresh and server-startup waiting into the MCP runtime's hook.
- Forward readiness waits through tool exposure and namespace wrappers.
- Test exact runtime selection for plain and namespaced tools, including
exposure overrides and missing tools.
GitOrigin-RevId: 8718589fa06f14d053a35a288186613f649d25ff
## What changed
- Split core tool planning from the assembly of MCP, extension, and dynamic tool runtimes.
- Build `ToolRouter` from a single ordered runtime list plus hosted tool specs.
- Centralize whether each `ToolExposure` variant is available in code mode.
- Preserve core, MCP, extension, and dynamic source ordering and existing name-collision priority.
## Testing
- Add coverage for unified source ordering and collisions, code-mode exposure, and standalone web search alongside MCP and dynamic `web.run` tools.
GitOrigin-RevId: b010c2e9728b92b75a35325ca9b2ec465c3bac12
## Why
`codex-http-client` is the intended owner of `reqwest`, while direct first-party
dependencies are tracked as migration debt.
## What changed
- Use `http` header and status types directly in core code and tests.
- Build the MCP test readiness client through `HttpClientBuilder`.
- Remove `reqwest` from `codex-core` and its temporary dependency-policy
exception.
GitOrigin-RevId: 8d5c7c86256294a7bb8aa1ae10cc5bea4cb1fc56
## What changed
- Propagate MCP tool `readOnlyHint` annotations through tool-call start and
completion events.
- Include the optional hint in persisted thread history and app-server
`mcpToolCall` items, preserving compatibility when the annotation is absent.
- Document that the hint describes tool capability, not the outcome of a
particular invocation.
## Testing
- Cover read-only and write-capable tools in live events and persisted rollout
data.
- Verify the hint survives thread reads and resumes for both in-progress and
completed MCP calls.
GitOrigin-RevId: dddfe905146075e5137a1094da485b86b99807f0
## Why
MCP catalog discovery must not allow a server to keep pagination running or
growing without bounds.
## What changed
- Apply the shared pagination collector to tool, resource, and resource-template
discovery.
- Limit each catalog to 100 pages and 1,024 items, and reject pagination cursors
larger than 64 KiB or any repeated cursor.
- Bound the entire pagination operation by the configured tool timeout, falling
back to 30 seconds when no timeout is configured.
## Testing
Add unit coverage for every limit and an end-to-end MCP test that preserves
valid multi-page tools while excluding a server that returns an oversized
cursor.
GitOrigin-RevId: 961a1bfa5fe8a265daf56e342a919c980cd720fa
## Why
A failed network policy amendment must not grant access to the requested host or approve it for the rest of the session.
## What changed
- Only approve the host for the session after the allow amendment is applied successfully.
- Otherwise deny the pending request and record a policy-denial outcome for its owning call.
## Testing
Added a managed-network regression test that submits an invalid allow amendment, verifies that the request is blocked, and confirms that retrying the host prompts for approval again.
GitOrigin-RevId: b2014d19128133abd5e19b8a7e4eb27810a45306
## What changed
- Add `thread/section/move` to atomically move a thread into, within, or out of a section. Threads can be inserted before an existing member or appended, and moves within a section preserve `sectionEnteredAt`.
- Add `section_position` sorting to `thread/list`, with ascending order as its default, and expose `sectionEnteredAt` in thread responses.
- Persist section positions and entry times in SQLite, including migration of existing section members into recency order. Section membership is no longer updated through `thread/metadata/update`.
## Testing
- Cover section moves, reordering, pagination, persistence across restarts and rollout reconciliation, concurrent updates, and rank renumbering.
GitOrigin-RevId: aec6d7ddedca5277029b5caf5c074975397e956c
## Why
File arguments for MCP app tools can use a path convention that differs from
the host running Codex. Resolving those arguments with host-native path handling
can therefore point uploads at the wrong file.
## What changed
- Resolve file arguments against the selected turn environment's working
directory with `PathUri::join`.
- Use the resolved URI's inferred native spelling for errors and derive the
uploaded filename without converting through a host-native path.
## Testing
Run the existing MCP file upload integration test under Wine and reduce its
streaming fixture to 2 MiB.
GitOrigin-RevId: 0a659c19e73f5a26ddfc864e39dad6a4a404057b
## What changed
- Update the Rust MCP SDK from `3.0.0-beta.3` to `3.0.0` and adapt to its renamed metadata and server discovery types.
- Accept discovery responses without server identity metadata, using the configured server name as a fallback, and rely on the SDK's native support for namespaced server identity metadata.
- Preserve typed OAuth HTTP errors so transport failures, cross-origin redirects, and transient HTTP responses are reported instead of being treated as anonymous access.
## Testing
- Cover modern discovery with namespaced or missing server identity over HTTP, SSE, and stdio.
- Cover OAuth discovery error propagation for transport failures, redirects, and transient status codes.
GitOrigin-RevId: 12c1e45136cca89ce4fb15986c2b5df14608682a
## What changed
- Consume owned rollout vectors when truncating fork and subagent history, reusing their allocations instead of copying slices.
- Project ephemeral fork responses and token-usage ownership before moving the source history into the new thread.
- Preserve canonical `beforeTurnId` validation for rolled-back and synthetic legacy turns.
## Testing
- Add truncation tests covering rolled-back and synthetic legacy `beforeTurnId` values.
GitOrigin-RevId: 5785d004b74d7e057b82379a172676b023bcfb4f
## What changed
- Set `encrypted_function_args` when constructing the router test's local tool call.
- Box the TUI test's app-server request payload to match `AppServerEvent::ServerRequest`.
GitOrigin-RevId: 45195f362bc912d202d95ea67271bcb102bf1e2a
## What changed
- Limit model-facing MCP namespace descriptions to 1,000 bytes without splitting UTF-8 characters or mutating the stored server metadata.
- Cap the aggregate source-description list in `tool_search` at 4 KiB while retaining source names and discovery instructions.
- Cover direct and deferred MCP tool exposure, including multibyte descriptions and tool visibility.
GitOrigin-RevId: 92736ec39475a1d6b3b03f5e3063e28225d8a5f6
## Why
Cached MCP definitions can make a tool callable before its server has finished
starting. Waiting for that server while holding the tool execution gate blocks
unrelated calls in the same response.
## What changed
- Expose the owning MCP server through tool runtime metadata, including tools
with exposure overrides.
- Refresh MCP state and wait for that specific server before entering the
parallel execution gate.
## Testing
Extend the cached MCP tool regression test to verify that an unrelated plan
update completes while MCP startup remains pending.
GitOrigin-RevId: 884d154bc403dfc1d347d265da3d6a887948e7b6
## Why
With deferred execution, an environment can become ready before a later step
spawns a sub-agent. The child must inherit the environment selections available
to that step.
## What changed
- Use the current step context's environment selections when spawning agents in
both multi-agent implementations.
- Add coverage that waits for a remote environment to become ready, spawns an
agent, and verifies that the child receives both remote and local selections.
GitOrigin-RevId: 97c37d541342bbefc9217bf341a19ebdfead2c76
## Why
An MCP tool call can run after its selected environment becomes ready, while the
turn context still contains the earlier starting-state snapshot. File argument
rewriting must use the environment available to the current step so it can
resolve and upload local files in that case.
## What changed
- Pass `StepContext` through MCP file argument rewriting.
- Resolve the primary environment from the step snapshot while retaining
turn-scoped configuration and metadata.
- Add coverage for an environment that transitions from starting to ready
during a turn.
GitOrigin-RevId: 935bea18ee425aabeacf4505eaff90565f9751e9
## What changed
- Add `EnvironmentManager::publish_ready_info` to update the selected capability
roots for an existing environment without replacing it.
- Store readiness as an atomically replaceable snapshot so repeated publications
expose the latest roots while deferred completion still controls connection
readiness.
- Validate published roots and reject updates for missing environments.
## Testing
- Cover publication, replacement, repeated and invalid updates, and interaction
with deferred environment completion.
GitOrigin-RevId: 1477f60e1319f840e6b33703ef2af052713779fd
## Why
When a turn uses multiple environments, the environment context lists each one but did not identify which environment is primary.
## What changed
- Add a `primary` attribute to each environment in multi-environment model context.
- Persist primary selection in world-state snapshots and emit updates when the primary environment changes.
- Restate environments when transitioning between single- and multi-environment context, while preserving the existing single-environment format.
## Testing
- Cover primary-environment changes, single/multi-environment transitions, legacy snapshot compatibility, and deferred-executor promotion after environment startup.
GitOrigin-RevId: 73a1d794a227edef6e9b7844e7f947b7f598dc80
## What changed
- Preserve `encrypted_function_args` on function calls so an empty list can mark plaintext collaboration arguments across request replay.
- Deliver `spawn_agent`, `send_message`, and `followup_task` payloads as structured plaintext agent messages when that marker is present; retain encrypted delivery otherwise.
- Redact plaintext collaboration arguments from tool and communication logs, and omit the metadata when sending requests to non-OpenAI providers.
## Testing
- Cover serialization of empty encrypted-argument metadata and plaintext versus encrypted subagent message delivery.
- Verify plaintext tool arguments are redacted and provider-specific metadata is removed from non-OpenAI requests.
GitOrigin-RevId: 64db98ff0b61a3af2f04ed609292363f2e2362a8
## What changed
- Add the stable, disabled-by-default `recommended_plugins` feature flag.
- Load recommended plugin candidates when apps and plugins are enabled and
either `tool_suggest` or `recommended_plugins` is active.
- Keep the `request_plugin_install` tool gated by `tool_suggest`.
## Testing
- Cover the first turn after external login with `tool_suggest` both enabled
and disabled, including the expected install-tool availability.
GitOrigin-RevId: 06d9a1c2e8dd2498a47796d833eb6d25ba528351
## What changed
- Propagate the initiating turn ID through agent spawns, follow-up tasks, reviews, and delegated Codex sessions.
- Add `parent_turn_id` to Responses client and turn metadata while keeping it out of external MCP metadata.
- Preserve parent-turn provenance across queued agent messages when their triggering parent is unambiguous.
## Testing
- Cover spawned, resumed, nested, reviewed, delegated, and WebSocket request metadata.
- Verify queued messages do not claim ambiguous or queue-only parent turns.
GitOrigin-RevId: 481fdebbe7df2031880fe259509273cce50b20a8
## What changed
- Use `https://api.openai.com/v1` for WebRTC sideband websocket joins instead of deriving the URL from the model provider.
- Keep `experimental_realtime_ws_base_url` as an explicit sideband override for local development and tests.
- Exclude provider query parameters when building sideband URLs.
## Testing
- Add coverage that a frameless sideband join uses `wss://api.openai.com/v1/live/rtc_test` even when the provider points at the ChatGPT backend.
- Update the sideband retry end-to-end test to inject its mock server URL through the new override.
GitOrigin-RevId: 5d3d2cd69905ba04143010ced36a22712825b563
## What changed
- Require callers to provide an HTTP client for MCP OAuth discovery and login, removing the separate direct `reqwest` path.
- Use the shared `http` and `url` types throughout the MCP client and drop its direct `reqwest` dependency.
- Preserve configured MCP headers when routing OAuth discovery through the provided client.
## Testing
- Add coverage that routed OAuth discovery forwards configured headers.
GitOrigin-RevId: 1345f56bd794626533133447597a5908e57b9b48
## What changed
Run the thread-title lookup alongside instruction refresh and plugin and skill
warmup, avoiding an additional sequential wait during session initialization.
GitOrigin-RevId: 021f48abeac249c5d3fe526d026bf031acf1bed9
## What changed
- Allocate 2% of the resolved model context window to skill metadata without
imposing the previous 4,000-token ceiling.
- Keep the 8,000-character fallback when no context window is available.
- Extend catalog rendering coverage to verify that a 400,000-token context
window receives an 8,000-token metadata budget and includes more skills.
GitOrigin-RevId: 5120d462de22fbfe5f9c4ab0d1bb97e51950d4b2
## Why
Matching model ETags can arrive on every response, but a recent models cache does
not need to be rewritten each time.
## What changed
Renew the models cache timestamp only after more than half of its configured TTL
has elapsed. Matching ETags continue to avoid refetching `/models`.
## Testing
Added integration coverage that verifies a recent cache remains unchanged and an
older cache is renewed without another `/models` request.
GitOrigin-RevId: b45da3824674c6b41d982ba4a405b419b09b7715
## Why
Rendering host and executor skill catalogs independently allows their combined
metadata to exceed the skills context budget.
## What changed
- Allocate one budget across both catalogs when both contain model-visible
skills.
- Prefer retaining executor skills when budget pressure requires omissions,
while preserving an executor omission marker and reporting when all host
skills were omitted.
- Evaluate absolute and aliased host paths under the shared budget and select
the rendering that best preserves executor entries, total entries, and
descriptions, in that order.
## Testing
Added renderer and production-turn coverage for shared-budget description
shortening, host-first omission, executor omission markers, and alias selection.
GitOrigin-RevId: 30041736a76aa173cb641aa98a876a306cb437d2
## Why
Host skill catalogs supplied through extension world state should report budget warnings only when their catalog update is actually rendered.
## What changed
- Stop rebuilding an extension-owned host catalog in core.
- Emit host catalog budget warnings when the corresponding world-state fragment is rendered, and deduplicate them with executor catalog warnings.
- Cover full, shortened, and omitted host and executor catalogs, including repeated turns and resumed persisted snapshots.
GitOrigin-RevId: ba28b6e337281b49ed4da2175c193fd4a6898ab7
## Why
An agent can be registered again with restored path metadata after a root thread
resumes. Leaving its previous registry entry behind can make later lookup and
release operations act on stale metadata.
## What changed
- Add a thread-to-path index alongside the agent tree.
- Keep both indexes synchronized when root and spawned agents are registered,
replaced, moved between paths, or released.
- Preserve other restored siblings when one agent is closed, while still
allowing a surviving sibling to be reloaded for follow-up work.
## Testing
Add registry coverage for replacement, release, and path migration, plus resume
tests with multiple sibling agents.
GitOrigin-RevId: 1c1acf422884a6842d9bbdf89ba993d98187770d
## Why
A pending optional MCP server can delay the first model request even when the
turn does not need that server.
## What changed
- Give optional MCP servers a shared one-second startup grace, then omit servers
that are still pending from the captured tool catalog.
- Continue waiting when the turn explicitly requires a server through a plugin,
skill dependency, or `mcp://` mention, and preserve this behavior for input
received between sampling steps.
- Route direct resource requests to the live connection set when a pending
server was omitted from the binding, while keeping all-server resource
discovery non-blocking.
## Testing
- Cover the shared grace period and resource behavior for pending optional
servers.
- Verify plugin, plugin-skill, and direct MCP mentions wait for startup.
- Verify an Apps-enabled turn proceeds without tools from an unrelated pending
optional server.
GitOrigin-RevId: b5f895c5a5362fe73f7d33250367662d4a217e4d
## What changed
- Add protocol types and `ResponseItem` helpers for attaching and clearing
locally recorded tool-call names and arguments.
- Bound serialized metadata across a prompt, replacing oversized arguments and
omitted calls with trusted truncation details.
- Prevent deserialized response items or model-provided arguments from forging
locally generated tool-call and truncation metadata.
## Testing
- Cover prompt-wide size limits, omission accounting, idempotent bounding, and
forged truncation markers.
GitOrigin-RevId: 960a223437ce81fe6b4cbb5fc7a9774408b2755b
## What changed
- Add an opt-in `mcp_2026_07_28` protocol mode while preserving the legacy
lifecycle by default.
- Negotiate the new protocol over streamable HTTP with `server/discover`,
including bounded responses, redirect protection, and fallback only when a
response establishes that the endpoint is legacy-only.
- Require stdio servers to opt in with
`CODEX_MCP_PROTOCOL_VERSION=2026-07-28`, and add a bounded local stdio
transport for the modern lifecycle.
- Consume paginated tool, resource, and resource-template catalogs in modern
mode, reject repeated cursors, and retain discovered server identity.
- Reconnect reusable MCP clients when their selected protocol mode changes.
## Testing
- Cover HTTP JSON and SSE discovery, legacy fallback and rejection cases,
redirects, retries, response limits, and pagination.
- Cover local and executor stdio discovery, protocol markers, message limits,
and legacy compatibility.
GitOrigin-RevId: f6a78816e127d2a482292d63b91c8384f1595903
## What changed
- Replace the `isPinned` thread metadata and filters with an optional persisted
`section` and `sectionId`.
- Add the paginated `threadSection/list` app-server method so clients can
discover sections even when they contain no threads.
- Seed a stable `Pinned` section, validate section assignments, and support
filtering for a specific section or for unsectioned threads.
## Testing
- Cover section protocol serialization, listing and pagination, metadata
updates, filtering, persistence, migration compatibility, and operation
without SQLite state.
GitOrigin-RevId: 7972b5471d29317b9387bfd90aa9f573f691ad4c
## Why
When the code mode host feature was disabled, thread startup always selected the in-process provider, even when `disable_in_process_fallback` was set.
## What changed
- Select a disabled provider when both the process host and in-process fallback are disabled.
- Return a clear tool error instead of running code mode in process for that configuration.
## Testing
Added an integration test covering code mode with the process host feature and in-process fallback both disabled.
GitOrigin-RevId: 3ed80afc23e0a5518c0133fe337a37b1fa545ead
## What changed
- Update the `rmcp` model and transport integrations for `3.0.0-beta.3`.
- Preserve legacy `elicitation/create` form requests, schema defaults, metadata, and wire-format compatibility while adopting the new elicitation types.
- Harden OAuth discovery by using GET-first discovery without starting an MCP session, preventing cross-origin header redirects, validating authorization-server and callback issuers, and retaining compatibility with metadata that omits an issuer.
- Keep stored OAuth credentials readable and avoid requiring reauthorization after transient refresh failures.
## Testing
- Add coverage for legacy elicitation round trips, OAuth discovery variants, callback issuer validation, credential migration, and refresh failures.
GitOrigin-RevId: 756197d26f3fd347c28c400228f6b3d06ed493b7