8.1 KiB
issue, issue_title
| issue | issue_title |
|---|---|
| 4 | config.json silently drops permission keys (defaultPolicy / bash / tools / ...) |
Warn on misplaced permission keys in config.json
Problem Statement
Users who paste permission-rule keys (defaultPolicy, tools, bash, mcp, skills, special, external_directory, doom_loop) into the extension's config.json get no feedback that those keys are silently ignored.
The file only governs extension runtime settings (debugLog, permissionReviewLog, yoloMode); permission rules belong in ~/.pi/agent/pi-permissions.jsonc, <project>/.pi/agent/pi-permissions.jsonc, or per-agent frontmatter.
Goals
- Detect permission-rule keys present in
config.jsonduring load. - Emit a clear, actionable warning naming the ignored keys and pointing to the correct files.
- Surface the warning via the permission review log and the existing
warningfield on the load result (which callers can display to stderr). - Produce no warning when
config.jsoncontains only valid extension keys.
Non-Goals
- Actually honoring permission rules in
config.json(two sources of truth is an anti-goal). - Validating the values of unrecognized keys (we only care about their presence).
- Changing the schema of
config.jsonor adding new extension settings (separate work).
Background
Relevant modules
src/extension-config.ts—normalizePermissionSystemConfigstrips everything except the three known keys.loadPermissionSystemConfigreturns aPermissionSystemConfigLoadResultwith an optionalwarningstring.src/types.ts—AgentPermissions/GlobalPermissionConfigdefine the permission-rule shape.src/logging.ts—PermissionSystemLogger.review()writes to the review log.
Permission surface
This is a config-loading concern, not a permission-surface change. No policy semantics, merge precedence, or on-disk identity are affected.
Design Overview
Misplaced-key detection
Define a constant set of keys that belong to the permission-policy schema, not the extension config:
const PERMISSION_POLICY_KEYS: ReadonlySet<string> = new Set([
"defaultPolicy",
"tools",
"bash",
"mcp",
"skills",
"special",
"external_directory",
"doom_loop",
]);
Where detection runs
Inside normalizePermissionSystemConfig (or a new companion function it calls), scan the incoming raw record for keys in PERMISSION_POLICY_KEYS.
Return both the normalized config and an array of misplaced key names (empty array = no problem).
The return type changes from bare PermissionSystemExtensionConfig to:
interface NormalizeResult {
config: PermissionSystemExtensionConfig;
configIssues: string[];
}
loadPermissionSystemConfig already has a warning field; when configIssues is non-empty, it builds a human-readable warning message and sets warning (appending to any pre-existing warning from ensurePermissionSystemConfig).
Warning message format
config.json contains permission-rule keys that are ignored here: defaultPolicy, bash, tools.
Permission rules belong in ~/.pi/agent/pi-permissions.jsonc, <project>/.pi/agent/pi-permissions.jsonc, or per-agent frontmatter.
See config/config.example.json for the keys config.json supports.
Edge cases
- Unknown keys that are not in
PERMISSION_POLICY_KEYS(e.g. a typo likedebuglog) — ignored for now; out of scope. - Empty
config.json({}) — no warning. - Multiple misplaced keys — all listed in a single warning.
Module-Level Changes
src/extension-config.ts
- Add
PERMISSION_POLICY_KEYSconstant. - Extract a
detectMisplacedPermissionKeys(raw: Record<string, unknown>): string[]function. - Change
normalizePermissionSystemConfigto returnNormalizeResult(config + configIssues). - Update
loadPermissionSystemConfigto readconfigIssuesand build the warning string when non-empty. - Combine any pre-existing warning from
ensurePermissionSystemConfigwith the misplaced-key warning (newline-separated).
tests/extension-config.test.ts (new file)
Focused unit tests for the detection and warning path.
config/config.example.json
No changes needed — file already shows only extension keys, which is the correct state.
schemas/permissions.schema.json
No changes — this schema governs the permission-policy file, not config.json.
TDD Order
-
Red: test that
detectMisplacedPermissionKeysreturns an empty array for a record with only valid extension keys.test: detectMisplacedPermissionKeys returns [] for clean config -
Green: implement
detectMisplacedPermissionKeysandPERMISSION_POLICY_KEYS.feat: detect misplaced permission keys in config.json (#4) -
Red: test that
detectMisplacedPermissionKeysreturns the correct key names when permission-rule keys are present alongside valid keys.test: detectMisplacedPermissionKeys lists misplaced keys -
Green: already passes from step 2 (or adjust).
-
Red: test that
normalizePermissionSystemConfigreturnsconfigIssueswith misplaced key names.test: normalizePermissionSystemConfig surfaces configIssues -
Green: update
normalizePermissionSystemConfigreturn type and wire in detection.feat: normalizePermissionSystemConfig returns configIssues (#4) -
Red: test that
loadPermissionSystemConfigsetswarningwhen config contains misplaced keys, and does not setwarningfor a clean config.test: loadPermissionSystemConfig warns on misplaced permission keys -
Green: update
loadPermissionSystemConfigto build the warning message fromconfigIssues.feat: loadPermissionSystemConfig warns on misplaced keys (#4) -
Docs: update
README.mdif it referencesconfig.jsonin a way that could mislead users into putting permission keys there.docs: clarify config.json vs permission-policy file (#4)
Risks and Mitigations
| Risk | Mitigation |
|---|---|
| Warning message is too noisy for users with valid configs | Warning only fires when misplaced keys are actually present; clean configs produce no output. |
| Could this silently weaken a permission? | No — this change only adds a warning. Permission resolution logic is untouched; misplaced keys are still ignored exactly as before. |
normalizePermissionSystemConfig return-type change breaks callers |
All call sites are in this repo (loadPermissionSystemConfig, savePermissionSystemConfig). Update them in the same commit. savePermissionSystemConfig only passes a typed PermissionSystemExtensionConfig, so it will never hit misplaced keys — but the type change must be handled. |
| Future extension keys could collide with permission-policy key names | Unlikely (PERMISSION_POLICY_KEYS names are domain-specific), but if it happens the key should be removed from the set at that time. |
Open Questions
None — the issue's proposed fix is unambiguous and self-contained.