Skip to content

feat: add support for policy definition configuration#85

Merged
reecebedding merged 3 commits into
mainfrom
feat/policy-behaviour-definitions
May 21, 2026
Merged

feat: add support for policy definition configuration#85
reecebedding merged 3 commits into
mainfrom
feat/policy-behaviour-definitions

Conversation

@reecebedding

@reecebedding reecebedding commented May 21, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features

    • Per-plugin policy behavior can be configured and is propagated across init, configure, and evaluation phases.
    • Defaults can be merged with configured mappings and applied to uncovered policy paths.
    • Ability to filter policy paths by behavior value for targeted evaluations.
  • Documentation

    • Configuration example now documents an optional policy_behavior section with key → label list mappings.
  • Tests

    • Added tests for conversion, merging, cloning, defaulting, and behavior-based path filtering.

Review Change Stack

Copilot AI review requested due to automatic review settings May 21, 2026 13:15
@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 895b20a6-3001-4efc-9a5d-4e8ded432ceb

📥 Commits

Reviewing files that changed from the base of the PR and between 88f2d8f and cdf6f1d.

📒 Files selected for processing (4)
  • README.md
  • cmd/agent.go
  • cmd/agent_test.go
  • runner/proto/policy_behavior.go

📝 Walkthrough

Walkthrough

This PR adds policy behavior configuration support throughout the agent's plugin lifecycle. It extends the runner proto contract with policy behavior mappings, implements helper methods for behavior manipulation and filtering, integrates configuration threading from agent startup through init/configure/eval phases, and updates tests to verify the new behavior flows.

Changes

Policy Behavior Configuration and Threading

Layer / File(s) Summary
Proto schema: StringList and policyBehavior fields
runner/proto/runner.proto
Introduces StringList message type and adds policyBehavior map fields (field 3) to ConfigureRequest, InitRequest, and EvalRequest to carry policy behavior configuration across runner boundaries.
EvalRequest policy behavior helper methods
runner/proto/policy_behavior.go
Implements WithDefaultPolicyBehavior (merges defaults), WithUndefinedMappedTo (maps uncovered paths), and PolicyPathsForBehavior (filters by behavior string). Includes internal mergePolicyBehavior and pathCoveredByPolicyBehavior helpers.
EvalRequest helper tests
runner/proto/policy_behavior_test.go
Tests cover nil handling, merging precedence, non-mutation of originals, and correct filtering for the three helper methods.
Agent plugin config and conversion helper
cmd/agent.go
Adds PolicyBehavior field to agentPlugin config structure and introduces policyBehaviorToProto helper that converts map[string][]string to proto map[string]*StringList format, deep-copying slices and returning nil for empty maps.
Agent lifecycle: init, configure, and eval request threading
cmd/agent.go
Threads policy behavior from agent plugin config through configureRunner and initRunner calls in both runAllPlugins and runPlugin code paths, converting to proto form and including it in InitRequest, ConfigureRequest, and EvalRequest payloads.
Agent test updates for expanded signatures and assertions
cmd/agent_test.go
Updates initRunner and configureRunner invocations across tests with trailing nil arguments; adds reflect import; asserts ConfigureRequest.PolicyBehavior is populated and adds TestPolicyBehaviorToProto.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I stitched StringLists into runner threads,
Paths now carry the behaviors we've fed,
Init, Configure, Eval in a tuneful line—
Policy maps hum, and the tests all shine!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add support for policy definition configuration' accurately describes the main change: adding support for a new policy_behavior configuration feature across the codebase.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for configuring “policy behavior” alongside policy paths so the agent can pass policy categorization/behavior metadata to runner plugins and provide helper logic for mapping policies to behaviors.

Changes:

  • Extend runner protobuf API (Configure/Init/Eval requests) to include a policyBehavior map and introduce a StringList wrapper message.
  • Add EvalRequest helpers to merge default behavior mappings, fill undefined mappings, and filter policy paths by behavior (with unit tests).
  • Wire policy_behavior from agent plugin configuration through to runner Configure, Init, and Eval calls.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
runner/proto/runner.proto Adds StringList and policyBehavior fields to request messages.
runner/proto/runner.pb.go Regenerates Go protobuf bindings to reflect the new API fields/types.
runner/proto/policy_behavior.go Introduces helper methods for default/undefined behavior mapping and behavior-based path filtering.
runner/proto/policy_behavior_test.go Adds unit tests covering behavior merging, undefined mapping, and filtering logic.
cmd/agent.go Plumbs policy_behavior config into runner Configure/Init/Eval requests and adds a conversion helper.
cmd/agent_test.go Updates tests to cover policyBehavior being sent on Configure and signature changes.
Files not reviewed (1)
  • runner/proto/runner.pb.go: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cmd/agent.go Outdated
Comment on lines +975 to +980
if policyBehavior == nil {
return nil
}
result := make(map[string]*proto.StringList)
for key, values := range policyBehavior {
result[key] = &proto.StringList{Values: values}
Comment on lines +100 to +105
func pathCoveredByPolicyBehavior(path string, behavior map[string]*StringList) bool {
for key := range behavior {
if strings.Contains(path, key) {
return true
}
}

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmd/agent_test.go`:
- Around line 1018-1020: The test directly indexes proto fields which can
nil-deref; change the assertion to use the generated getters: fetch the policy
bundle via pb :=
testRunner.configureRequest.GetPolicyBehavior()["policy-bundle"] (or check for
nil first), then obtain values with pb.GetValues() (guarding pb == nil) and
compare that slice to the expected []string{"vpc","sg"} using reflect.DeepEqual;
update the test to handle the nil pb case explicitly so no direct field access
occurs.

In `@runner/proto/policy_behavior.go`:
- Around line 25-29: The local variable named copy shadows Go's predeclared copy
builtin; rename that variable (e.g., change copy to cloned or clonedReq) where
the EvalRequest is constructed so references to EvalRequest{PolicyPaths:
slices.Clone(r.PolicyPaths), ApiServer: r.ApiServer, PolicyBehavior:
mergePolicyBehavior(nil, r.PolicyBehavior)} no longer use the identifier copy;
update all subsequent uses of that variable in the function to the new name to
avoid shadowing and lint failures.

In `@runner/proto/runner.proto`:
- Line 20: Rename the protobuf field policyBehavior to policy_behavior in all
affected message definitions (ConfigureRequest, InitRequest, and EvalRequest) so
it follows lower_snake_case; keep the value type as map<string, StringList> so
the generated Go field remains PolicyBehavior. Update all references/usages in
proto comments or options accordingly and then regenerate the Go artifacts
(protoc/buf) to pick up the renamed field. Ensure any code that referenced the
old proto field name is updated to use the regenerated Go field or the new proto
field name where applicable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2d8f1c00-34fa-4574-af8c-bc07608b5993

📥 Commits

Reviewing files that changed from the base of the PR and between 753ca81 and a5fbd2b.

⛔ Files ignored due to path filters (1)
  • runner/proto/runner.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (5)
  • cmd/agent.go
  • cmd/agent_test.go
  • runner/proto/policy_behavior.go
  • runner/proto/policy_behavior_test.go
  • runner/proto/runner.proto

Comment thread cmd/agent_test.go Outdated
Comment thread runner/proto/policy_behavior.go Outdated
Comment thread runner/proto/runner.proto
message ConfigureRequest {
map<string, string> config = 1;
google.protobuf.Struct policy_data = 2;
map<string, StringList> policyBehavior = 3;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the referenced proto file around the mentioned lines
echo "== runner/proto/runner.proto (context around lines ~1-60) =="
nl -ba runner/proto/runner.proto | sed -n '1,120p'

echo
echo "== Search for policyBehavior in the repo =="
rg -n "policyBehavior" -S .

echo
echo "== Search for policy_behavior in the repo =="
rg -n "policy_behavior" -S .

Repository: compliance-framework/agent

Length of output: 192


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Confirm file exists =="
ls -la runner/proto/runner.proto || true

echo
echo "== runner/proto/runner.proto (first 120 lines with line numbers) =="
python3 - <<'PY'
import itertools
path = "runner/proto/runner.proto"
with open(path, "r", encoding="utf-8") as f:
    for i, line in zip(range(1, 121), f):
        print(f"{i:4d}\t{line.rstrip()}")
PY

echo
echo "== Search for policyBehavior in the repo =="
rg -n "policyBehavior" -S .

echo
echo "== Search for policy_behavior in the repo =="
rg -n "policy_behavior" -S .

Repository: compliance-framework/agent

Length of output: 5023


Rename proto field policyBehavior to policy_behavior to satisfy Buf/protobuf naming lint

runner/proto/runner.proto defines policyBehavior in ConfigureRequest, InitRequest, and EvalRequest; protobuf field names should be lower_snake_case. Renaming to policy_behavior keeps the Go generated field name as PolicyBehavior.

Suggested fix
 message ConfigureRequest {
   map<string, string> config = 1;
   google.protobuf.Struct policy_data = 2;
-  map<string, StringList> policyBehavior = 3;
+  map<string, StringList> policy_behavior = 3;
 }
@@
 message InitRequest {
   repeated string policyPaths = 1;
   uint32 apiServer = 2;
-  map<string, StringList> policyBehavior = 3;
+  map<string, StringList> policy_behavior = 3;
 }
@@
 message EvalRequest {
   repeated string policyPaths = 1;
   uint32 apiServer = 2;
-  map<string, StringList> policyBehavior = 3;
+  map<string, StringList> policy_behavior = 3;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
map<string, StringList> policyBehavior = 3;
map<string, StringList> policy_behavior = 3;
🧰 Tools
🪛 Buf (1.69.0)

[error] 20-20: Field name "policyBehavior" should be lower_snake_case, such as "policy_behavior".

(FIELD_LOWER_SNAKE_CASE)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@runner/proto/runner.proto` at line 20, Rename the protobuf field
policyBehavior to policy_behavior in all affected message definitions
(ConfigureRequest, InitRequest, and EvalRequest) so it follows lower_snake_case;
keep the value type as map<string, StringList> so the generated Go field remains
PolicyBehavior. Update all references/usages in proto comments or options
accordingly and then regenerate the Go artifacts (protoc/buf) to pick up the
renamed field. Ensure any code that referenced the old proto field name is
updated to use the regenerated Go field or the new proto field name where
applicable.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
cmd/agent_test.go (1)

1065-1066: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use proto getters in this new assertion to satisfy protogetter and avoid nil dereference.

Line 1065 still directly accesses got["bundle"].Values. Switch to GetValues() in both the assertion and failure message.

Suggested fix
-		if !reflect.DeepEqual(got["bundle"].Values, want) {
-			t.Fatalf("policyBehaviorToProto() values = %#v, want %#v", got["bundle"].Values, want)
+		bundle := got["bundle"]
+		if !reflect.DeepEqual(bundle.GetValues(), want) {
+			t.Fatalf("policyBehaviorToProto() values = %#v, want %#v", bundle.GetValues(), want)
 		}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/agent_test.go` around lines 1065 - 1066, The test assertion directly
accesses got["bundle"].Values which can nil-deref; replace both uses with the
proto getter: call got["bundle"].GetValues() in the reflect.DeepEqual check and
in the t.Fatalf message (e.g., change policyBehaviorToProto() values = %#v to
use got["bundle"].GetValues()), so the test uses the proto getter API and avoids
nil dereference.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@cmd/agent_test.go`:
- Around line 1065-1066: The test assertion directly accesses
got["bundle"].Values which can nil-deref; replace both uses with the proto
getter: call got["bundle"].GetValues() in the reflect.DeepEqual check and in the
t.Fatalf message (e.g., change policyBehaviorToProto() values = %#v to use
got["bundle"].GetValues()), so the test uses the proto getter API and avoids nil
dereference.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: adee60d8-b117-44e0-9e3a-1591865848dd

📥 Commits

Reviewing files that changed from the base of the PR and between a5fbd2b and 88f2d8f.

📒 Files selected for processing (4)
  • cmd/agent.go
  • cmd/agent_test.go
  • runner/proto/policy_behavior.go
  • runner/proto/policy_behavior_test.go

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated 3 comments.

Files not reviewed (1)
  • runner/proto/runner.pb.go: Language not supported

Comment thread cmd/agent.go
return nil
}
result := make(map[string]*proto.StringList, len(policyBehavior))
for key, values := range policyBehavior {
Comment on lines +65 to +73
filtered := make([]string, 0, len(r.PolicyPaths))
outer:
for _, path := range r.PolicyPaths {
for _, key := range matchingKeys {
if pathCoveredByPolicyBehavior(path, map[string]*StringList{key: nil}) {
filtered = append(filtered, path)
continue outer
}
}
Comment thread cmd/agent_test.go
Comment on lines 950 to 966
@@ -961,6 +962,7 @@ func TestInitRunner(t *testing.T) {
&initTestRunner{initErr: status.Error(codes.Unimplemented, "not implemented")},
nil,
nil,
nil,
)
@reecebedding reecebedding merged commit bf76279 into main May 21, 2026
4 checks passed
@reecebedding reecebedding deleted the feat/policy-behaviour-definitions branch May 21, 2026 13:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants