refactor: use Config::global() instead of per-instance config in SACP server#8893
refactor: use Config::global() instead of per-instance config in SACP server#8893
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 36d4ff286a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
AI comment: This removes the agent-owned config path, so If ACP should always use process-global config, should we remove |
Replace all Config::new(config_dir.join(...), "goose") calls in the SACP server with Config::global(), which uses the same default path but goes through the shared singleton mutex. This: - Serializes all config read-modify-write operations (same protection as Goose 1's REST server) - Fixes a keyring bug where Config::new() hardcoded SecretStorage::Keyring and ignored the GOOSE_DISABLE_KEYRING env var - Eliminates inconsistency where some handlers already used Config::global() while config CRUD handlers used the per-instance Config::new() path - Removes the now-unnecessary config_dir field, load_config/config methods, and CONFIG_YAML_NAME import from the SACP server Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…CP server Remove the unnecessary bare block around Config::global() usage in resolve_provider_and_model_with_inventory_refresh. Since Config::global() returns &'static Config and cannot fail, the extra block scope (left over from the old fallible Config::new() error-handling pattern) serves no purpose. Removing it flattens indentation by one level. Also fix three clippy::needless_borrow warnings where &config was passed but config is already &'static Config, so the extra reference is immediately dereferenced by the compiler. Signed-off-by: Matt Toohey <contact@matttoohey.com>
Add Config::init_global(config_dir) that initializes the global singleton with a caller-provided config directory instead of the default. This addresses PR feedback that Config::global() silently ignored the config_dir field from AcpServerFactoryConfig. The server factory now calls init_global(config_dir) so that if a non-default config directory is ever passed, the global Config will use the correct path while still providing the singleton mutex serialization benefit. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Build Config::init_global from the same config path stack as Config::default and return an error when an existing global config points at a different writable path. Validate that invariant from GooseAcpAgent::new so direct ACP callers cannot silently use a stale global config. Update ACP fixtures to use one process-global test config directory and add a regression test for mismatched config directories. Signed-off-by: Matt Toohey <contact@matttoohey.com>
70382ad to
66b8f26
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 66b8f26323
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| let config = Config::global(); | ||
| let ext_state = EnabledExtensionsState::extensions_or_default( | ||
| Some(&goose_session.extension_data), | ||
| config, | ||
| ); |
There was a problem hiding this comment.
Invalidate secret cache before prebuilding providers
This session-init refresh path now constructs a provider from Config::global() without clearing secrets_cache, but the previous implementation explicitly invalidated it first. If secrets.yaml/keyring is updated out-of-band while the process stays up, a new session can still prebuild and refresh inventory with stale credentials until another endpoint happens to call invalidate_secrets_cache(), which regresses secret-rotation behavior during normal session startup.
Useful? React with 👍 / 👎.
| if self.write_path() == requested { | ||
| return Ok(()); |
There was a problem hiding this comment.
Canonicalize paths before enforcing global config match
The new global-config guard compares raw PathBuf equality, so equivalent paths with different spellings (for example relative vs absolute, or symlinked aliases) are treated as mismatches and return GlobalConfigPathMismatch. That can make init_global fail nondeterministically for the same underlying config directory depending on caller path formatting, even though no real directory conflict exists.
Useful? React with 👍 / 👎.
Add Config::for_config_dir with a path-normalized cache so custom ACP config directories share one Config mutex and secrets cache without forcing them through the global singleton. Keep the default config path on Config::global(). Store the selected config handle on GooseAcpAgent and use it for the ACP paths that previously built a per-request Config, including session provider/model resolution and generic config/secret custom requests. Update ACP fixtures and regression coverage for default/global handling, custom-directory coexistence, equivalent path normalization, shared state, and concurrent config upserts. Signed-off-by: Matt Toohey <contact@matttoohey.com>
This matches how the older REST APIs handled concurrent requests regarding config
Summary
Config::new()calls withConfig::global()across SACP server and server factory, eliminating redundant config file readsconfig_dirfield andload_config()/config()helper methods fromGooseAcpAgent, since they are no longer needed🤖 Generated with Claude Code