Uh oh!
There was an error while loading. Please reload this page.
feat(settings): gateway-to-sandbox runtime settings channel - #474
Conversation
|
4d4e3ce to
85fef54Comparepimlock
commented
Mar 19, 2026
Few questions after first pass
|
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
johntmyers
commented
Mar 20, 2026
Right now they would succeed in updating the sandbox policy, but have no effect until the global policy was taken down. This is def a UX bug. Good call out. My thinking is we block chunk approval while a global policy is active. This isn't a one-way door and is the safest thing to do. Other options:
So I think we just disallow approving chunks when a global policy is active. |
johntmyers
commented
Mar 20, 2026
Okay we block rule acceptance when a global policy is set. I think we can go with this for now. |
Closes#405 Refactor the sandbox policy polling channel into an effective settings response with config revision tracking, global policy source metadata, and merged global/sandbox key resolution. Add gateway-global and sandbox-scoped setting mutations with per-key mutual exclusion, global delete unlock semantics, and global policy override behavior. Extend the CLI with settings get/set/delete and --global policy flows, then document the new control-plane behavior in architecture and user docs. Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
…ditionally reload policy
…read-modify-write races
… consolidate TUI utils
…d auto-refresh sandbox settings
…and sandbox effects
00c9461 to
1998927CompareUh oh!
There was an error while loading. Please reload this page.
* feat(gateway/sandbox): add global and sandbox runtime settings flow
Summary
Adds a general-purpose settings channel between the gateway and sandboxes, enabling runtime configuration changes without sandbox restarts. This separates the settings transport concern from issue #393 (OCSF logging) so it can land independently.
Related Issue
Closes#405
UX Changes
CLI
New commands:
openshell settings get [sandbox] [--global] [--json]-- show effective settings with scope indicators (sandbox/global/unset)openshell settings set [sandbox] --key K --value V [--global] [--yes]-- set a setting at sandbox or global scopeopenshell settings delete [sandbox] --key K [--global] [--yes]-- delete a setting (sandbox-scoped when not globally managed, or global)openshell policy list --global-- list global policy revision historyopenshell policy get --global [--rev N] [--full]-- show a specific global policy revisionChanged commands:
openshell policy set --globalnow creates versioned revisions (deduped by hash) instead of overwriting in-placeopenshell policy set --global --waitis rejected with a message ("global policies are effective immediately")--globalmutations require HITL confirmation (bypass with--yes)Scope resolution:
FailedPrecondition.TUI
Dashboard:
Providers | Global Settings(switch withh/l)Global Policy Active (v3)in yellow when a global policy is setSandbox screen:
Policy | Settings(switch withh/l)Policy: managed globally (v3)when sandbox policy is globally overriddenSandbox Logs
Policy poll:toSettings poll:Setting changed key=log_level new=debug old=<unset>Policy reloaded successfullyonly appears when the policy hash actually changed (not for settings-only changes)global_version=Nin the logArchitecture (tl;dr)
Proto changes (
sandbox.proto,openshell.proto)New types:
SettingValue(oneof string/bool/int64/bytes),EffectiveSetting(value + scope),SettingScope,PolicySource.New RPCs:
GetSandboxSettings-- returns effective policy + merged settings + config_revision + global_policy_versionGetGatewaySettings-- returns global-only settingsRenamed:
UpdateSandboxPolicy->UpdateSettings-- now handles policy and setting mutations at both scopes through field-based dispatch (global,setting_key,setting_value,delete_setting).Extended:
GetSandboxPolicyStatusandListSandboxPoliciesgained aglobalbool to query global policy revisions.Settings storage
Settings are stored as JSON blobs in the existing
objectstable withgateway_settingsandsandbox_settingsobject types. Sandbox settings use a prefixed ID (settings:{sandbox_uuid}) to avoid PK collision with sandbox objects. Atokio::sync::Mutexserializes all settings mutations to prevent read-modify-write races.Global policy versioning
Global policies are now versioned in the
sandbox_policiestable using a sentinelsandbox_idof__global__. Revisions are markedloadedimmediately (no sandbox confirmation for global policies). The existingget_latest_policy,list_policies, andsupersede_older_policiesStore methods work unchanged with the sentinel.Settings registry (
openshell-core/src/settings.rs)Compile-time
REGISTERED_SETTINGSarray defines allowed keys with typedSettingValueKind. Test keys (dummy_bool,dummy_int) gated behinddev-settingsfeature flag (on by default). The doc comment on the registry documents the process for adding new settings.Config revision
config_revisionis a 64-bit content hash (first 8 bytes of SHA-256 over policy + settings + source). The sandbox poll loop compares it to detect changes. Not a monotonic counter -- useswrapping_addfor the settings revision counter.TUI Dashboard with a global policy set:
Sandbox view with a global policy and one global setting override:
Changes
GetSandboxSettings/GetGatewaySettingsRPCs,UpdateSettingsrename, global flag on policy status/list RPCs,global_policy_versionfieldsettings get/set/delete,policy list/get --global,--jsonoutput,--waitrejection for globalparse_bool_like,display_setting_valuesettings_management.rscovering full lifecycle (sandbox set/delete, global override, lock/unlock)openshell-coreandopenshell-server(merge algorithm, conflict guard, delete-unlock, concurrency, round-trips)Testing
mise run pre-commitpassessettings_management.rs)Checklist