fix(settings): guard /settings dialog to project-scoped keys#106
Merged
Conversation
Policy follow-up to #105: settings that persist at user level must not be editable via /settings — a dialog edit to a non-allowlisted key would land in ~/.{app}/settings.json and silently apply across all projects of the app. _build_ui_items() now excludes (with a per-key warning) any key whose target field is not in PROJECT_SETTABLE_KEYS, regardless of what a domain app returns from get_ui_setting_keys(). The synthetic "model" key passes via the _UI_KEY_TARGET_FIELDS alias (set_model() writes default_model, which is allowlisted). Dangling keys for removed fields (e.g. airesearcher's log_activity) now warn instead of being silently skipped. Programmatic update_setting()/save_settings() with user-scoped keys stays legitimate — the split-save from #105 remains their writer; the dialog just can't produce them. Claude-Session: https://claude.ai/code/session_01SwkKXQpy3JLEqrPkQA8QRv
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Policy
Follow-up to #105, per review discussion: settings that persist at user level must not be editable via
/settings. A dialog edit to a non-allowlisted key would land in the user~/.{app}/settings.jsonand silently apply across all projects of the app.Change
_build_ui_items()— the single funnel every dialog item passes through — now excludes any key whose target field is not inPROJECT_SETTABLE_KEYS, logginguser_scoped_setting_excluded_from_uiper key so app developers discover the policy at dev time instead of debugging a missing item. Since the dialog result dict can only contain keys of rendered items, this one check covers the whole/settingspath.Details:
modelkey passes via a_UI_KEY_TARGET_FIELDSalias (set_model()writesdefault_model, which is allowlisted). Any future synthetic key must declare its target field or it is excluded — deny-by-default, same posture as P0-1.log_activity) now warn instead of being silently skipped.update_setting()/save_settings()with user-scoped keys stays legitimate — the trust-split save from fix(settings): trust-split save so /settings changes survive the P0-1 allowlist #105 remains their writer; the dialog just can't produce them.Current exposure audit (why this is safe to enforce now): base dialog shows
model+thinking_effort; research_demo addsverbose_thinking— all project-scoped, so nothing visible changes for existing apps.Tests
TDD: 4 tests in
tests/cli/test_settings_ui_scope.pywritten first and watched fail — user-scoped key excluded with warning, allowlisted keys render warning-free,modelpasses the guard, dangling key warns. Full offline suite: 1981 passed.https://claude.ai/code/session_01SwkKXQpy3JLEqrPkQA8QRv