fix(agent-core-v2): load config permission rules into agents at bootstrap - #2970
fix(agent-core-v2): load config permission rules into agents at bootstrap#2970N123999 wants to merge 3 commits into
Conversation
🦋 Changeset detectedLatest commit: 7c51047 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3db334f17b
ℹ️ 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".
1548319 to
34c35b5
Compare
|
@codex review |
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
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". |
…trap The `permission` config section (`[[permission.rules]]`) had a schema and TOML transforms but no consumer: nothing ever called `IAgentPermissionRulesService.addRules` in production, and since `permission.rules.add` is a transient op, a restored agent's rules model always started empty. Every Bash call therefore fell through to the `fallback-ask` policy even when the user had configured allow/deny rules. Apply the configured rules in `AgentLifecycleService.bindBootstrap`, right after `wire.restore()`, mirroring the existing `defaultPermissionMode` handling. Every v2 agent creation path (main agent, subagent, btw fork, session fork; TUI / kimi -p / kimi acp / kimi web) converges on this point, so config rules are injected exactly once per materialization and re-read from config.toml on resume, without touching the restored session-approval memory carried by persisted `permission.record_approval_result` records. Closes MoonshotAI#2964
34c35b5 to
7c51047
Compare
Related Issue
Closes #2964
Problem
Since 0.33.0 the interactive TUI,
kimi -p, andkimi acprun on the agent-core-v2 engine by default. Under v2,[[permission.rules]]in~/.kimi-code/config.toml(e.g.{ decision = "allow", pattern = "Bash(ls*)" }) has no effect at all — every matching Bash call still prompts for approval. Root cause, in three parts:permissionconfig section has a complete schema and TOML transforms and self-registers at module load (packages/agent-core-v2/src/agent/permissionRules/configSection.ts), but after registration it has no consumer anywhere in the repo.IAgentPermissionRulesService.addRuleshas no production call site (only tests call it). Agent materialization replays only persisted records viawire.restore(), andpermission.rules.addis a transient op, so after restore the rules model is always empty.user-configured-allow/deny/askpolicies can never match, and unmatched calls fall through tofallback-askat the end of the policy chain.v1 had this wiring: session create/resume passed
config.permission?.rulesinto the PermissionManager. The v2 port dropped it.What changed
One change point:
AgentLifecycleService.bindBootstrap(packages/agent-core-v2/src/session/agentLifecycle/agentLifecycleService.ts). Afterwire.restore(), it now reads thepermissionsection throughIConfigServiceand appliesrulesviaIAgentPermissionRulesService.addRules, mirroring the existingdefaultPermissionModeblock in the same function.Why the engine-side bootstrap point rather than host-side injection:
kimi -p/kimi acp/kimi weball run the engine in-process, and session create/resume converges onIAgentLifecycleService.create→bindBootstrap; subagents (Agent tool), btw forks, and session forks are materialized through the same entry. Host-side injection would need touch points in node-sdk, acp-server, and kap-server, and would still miss agents created inside the engine.IConfigService, never passed around as a config bag via options;defaultPermissionModeanddefaultPlanModeare existing precedents of the engine applying a config section at bootstrap.permission.rules.addis a transient op, so the rules model starts empty on restore andbindBootstrapre-reads the currentconfig.toml— rule edits between runs take effect on the next resume, injection happens exactly once per materialization, and the approval memory replayed from persistedpermission.record_approval_resultrecords is untouched.create→bindBootstrappath — the net effect matches v1, where subagents shared the parent's PermissionManager.Tests: extended
packages/agent-core-v2/test/session/agentLifecycle/agentLifecycle.test.ts— rules from config are loaded into the agent on create;addRulesis not called when the section is missing or the list is empty; on resume the config rules are re-injected while the restored session-approval patterns are preserved (and nothing is re-persisted); and a config-sourced deny rule actually blocks a matching tool call through the real policy chain (user-configured-deny).Screenshots
Before (0.36.1):
lsprompts for approval despite[[permission.rules]]allowingBash(ls*). After (this branch): the same prompt runslsdirectly, no approval dialog.Checklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update. (No doc update needed — the fix restores the already-documented[[permission.rules]]behavior.)