From c2f62b2a2ba52b7edea3a3d3624162ec38096b97 Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Fri, 13 Feb 2026 12:02:07 -0800 Subject: [PATCH] docs: fix inconsistent commandRegex example in policy engine (#19027) --- docs/core/policy-engine.md | 6 ++++-- packages/core/src/policy/toml-loader.test.ts | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/docs/core/policy-engine.md b/docs/core/policy-engine.md index a99a6652d8..23e672e4b9 100644 --- a/docs/core/policy-engine.md +++ b/docs/core/policy-engine.md @@ -208,9 +208,11 @@ commandPrefix = "git " # (Optional) A regex to match against the entire shell command. # This is also syntactic sugar for `toolName = "run_shell_command"`. -# Note: This pattern is tested against the JSON representation of the arguments (e.g., `{"command":""}`), so anchors like `^` or `$` will apply to the full JSON string, not just the command text. +# Note: This pattern is tested against the JSON representation of the arguments (e.g., `{"command":""}`). +# Because it prepends `"command":"`, it effectively matches from the start of the command. +# Anchors like `^` or `$` apply to the full JSON string, so `^` should usually be avoided here. # You cannot use commandPrefix and commandRegex in the same rule. -commandRegex = "^git (commit|push)" +commandRegex = "git (commit|push)" # The decision to take. Must be "allow", "deny", or "ask_user". decision = "ask_user" diff --git a/packages/core/src/policy/toml-loader.test.ts b/packages/core/src/policy/toml-loader.test.ts index f46e474442..c627f6d049 100644 --- a/packages/core/src/policy/toml-loader.test.ts +++ b/packages/core/src/policy/toml-loader.test.ts @@ -111,6 +111,24 @@ priority = 100 expect(result.errors).toHaveLength(0); }); + it('should NOT match if ^ is used in commandRegex because it matches against full JSON', async () => { + const result = await runLoadPoliciesFromToml(` +[[rule]] +toolName = "run_shell_command" +commandRegex = "^git status" +decision = "allow" +priority = 100 +`); + + expect(result.rules).toHaveLength(1); + // The generated pattern is "command":"^git status + // This will NOT match '{"command":"git status"}' because of the '{"' at the start. + expect( + result.rules[0].argsPattern?.test('{"command":"git status"}'), + ).toBe(false); + expect(result.errors).toHaveLength(0); + }); + it('should expand toolName array', async () => { const result = await runLoadPoliciesFromToml(` [[rule]]