mark Feature::RemoteControl as removed (#22386)

## Why

`remote_control` can appear in `config.toml`, CLI feature overrides, and
the app-server config APIs. Before this PR, app-server startup treated
`config.features.enabled(Feature::RemoteControl)` as the signal to start
remote control ([base
code](https://github.com/openai/codex/blob/5e3ee5eddfa5333f2e0b011880abf0cbf92bd295/codex-rs/app-server/src/lib.rs#L678-L680)).
That meant a user with:

```toml
[features]
remote_control = true
```

would accidentally opt every app-server process into remote control.
Remote-control startup should instead be a per-process launch decision
made by CLI flags.

## What Changed

- Marks `Feature::RemoteControl` as `Stage::Removed`, keeping
`remote_control` as a known compatibility key while making it
config-inert.
- Adds a hidden `--remote-control` process flag to `codex app-server`
and standalone `codex-app-server`.
- Plumbs that flag through
`AppServerRuntimeOptions.remote_control_enabled` and makes app-server
startup use only that runtime option to decide whether to start remote
control.
- Removes the app-server config mutation hook that reloaded config and
toggled remote control at runtime.
- Updates managed daemon spawning to use `codex app-server
--remote-control --listen unix://` instead of `--enable remote_control`.

Config APIs can still list, read, write, and set `remote_control`; those
operations just no longer affect remote-control process enrollment.
This commit is contained in:
Owen Lin
2026-05-13 00:52:45 +00:00
committed by GitHub
parent 1ae9867296
commit 2237a13cf1
11 changed files with 30 additions and 47 deletions
@@ -6,7 +6,6 @@ use crate::error_code::internal_error;
use crate::error_code::invalid_request;
use crate::outgoing_message::ConnectionRequestId;
use crate::outgoing_message::OutgoingMessageSender;
use crate::transport::RemoteControlHandle;
use codex_analytics::AnalyticsEventsClient;
use codex_app_server_protocol::AppListUpdatedNotification;
use codex_app_server_protocol::ClientResponsePayload;
@@ -39,7 +38,6 @@ use codex_config::MatcherGroup as CoreMatcherGroup;
use codex_config::ResidencyRequirement as CoreResidencyRequirement;
use codex_config::SandboxModeRequirement as CoreSandboxModeRequirement;
use codex_core::ThreadManager;
use codex_features::Feature;
use codex_features::canonical_feature_for_key;
use codex_features::feature_for_key;
use codex_login::AuthManager;
@@ -67,7 +65,6 @@ pub(crate) struct ConfigRequestProcessor {
auth_manager: Arc<AuthManager>,
thread_manager: Arc<ThreadManager>,
analytics_events_client: AnalyticsEventsClient,
remote_control_handle: Option<RemoteControlHandle>,
}
impl ConfigRequestProcessor {
@@ -77,7 +74,6 @@ impl ConfigRequestProcessor {
auth_manager: Arc<AuthManager>,
thread_manager: Arc<ThreadManager>,
analytics_events_client: AnalyticsEventsClient,
remote_control_handle: Option<RemoteControlHandle>,
) -> Self {
Self {
outgoing,
@@ -85,7 +81,6 @@ impl ConfigRequestProcessor {
auth_manager,
thread_manager,
analytics_events_client,
remote_control_handle,
}
}
@@ -187,21 +182,6 @@ impl ConfigRequestProcessor {
pub(crate) async fn handle_config_mutation(&self) {
self.thread_manager.plugins_manager().clear_cache();
self.thread_manager.skills_manager().clear_cache();
let Some(remote_control_handle) = &self.remote_control_handle else {
return;
};
match self.load_latest_config(/*fallback_cwd*/ None).await {
Ok(config) => {
remote_control_handle.set_enabled(config.features.enabled(Feature::RemoteControl));
}
Err(error) => {
tracing::warn!(
"failed to load config for remote control enablement refresh after config mutation: {}",
error.message
);
}
}
}
async fn handle_config_mutation_result<T>(