Skip to content

Add standalone approval slots - #1418

Open
rishiz27 wants to merge 5 commits into
developfrom
rzarkar/standalone-approval-slots
Open

rishiz27 wants to merge 5 commits into
developfrom
rzarkar/standalone-approval-slots

Conversation

@rishiz27

Copy link
Copy Markdown

Adds approval slots that you can fill with rules from the same policy file. Required slots have to be filled, and multiple rules in a slot stay grouped together. The details page shows filled slots and hides empty ones.

@changelog-app

changelog-app Bot commented Oct 16, 2026

Copy link
Copy Markdown

Generate changelog in changelog/@unreleased

Type (Select exactly one)

  • Feature (Adding new functionality)
  • Improvement (Improving existing functionality)
  • Fix (Fixing an issue with existing functionality)
  • Break (Creating a new major version by breaking public APIs)
  • Deprecation (Removing functionality in a non-breaking way)
  • Migration (Automatically moving data/functionality to a new system)

Description

adding standalone approval slots

Check the box to generate changelog(s)

  • Generate changelog entry

@asvoboda asvoboda changed the title adding standalone approval slots Add standalone approval slots Nov 5, 2026
Comment thread server/handler/pull_request_review.go Outdated
evaluator, err := evalCtx.ParseConfig(ctx, common.TriggerReview)
// COMMENTED reviews also supply approval comments, and dismissing a review
// can remove one even when GitHub review approvals are disabled.
evaluator, err := evalCtx.ParseConfig(ctx, common.TriggerReview|common.TriggerComment)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Are these changes necessary for slots? I'd like to see the minimal set of changes here. If this is a bug, lets separate it into its own PR (or set of PRs)?

Comment thread server/handler/issue_comment.go Outdated
return err
}

// Audit unused rules too, even when ParseConfig found no comment trigger.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why is this necessary? Now the tampering check is removed?

}
}
result := r.Child.Evaluate(ctx, prctx)
result.Slot = &common.SlotResult{Name: r.Name}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this means that a filled slot still renders as the implicit and wrapper, even for a single-rule fill. Is that intentional? The RFC described slot content as "flattened". Should the result take the slot's name, or should we skip the wrapper when the fill has one entry? It isn't a correctness issue, but it's the first thing users will see.

Comment thread policy/policy.go
return nil, errors.WithMessage(err, "failed to parse approval policy")
}
for name, fill := range c.Slots {
if name == "" || fill == nil {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The empty-name check is in both Slots.UnmarshalYAML and ParsePolicy. I'd keep one and remove the other?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

kept it in policy parsing

Comment thread policy/slots_test.go Outdated
assert.Equal(t, expected, result.Status)
}
// OR may suppress the aggregate error, but retains child evidence.
assert.Error(t, result.Children[0].Children[0].Children[1].Error)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this is a pretty brittle assertion

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

agreed changed it to find by name instead

@@ -94,7 +94,7 @@ func TestParsePolicy(t *testing.T) {
rulesByName[r.Name] = r

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd suggest adding a slot declaration and a filled slot to to the testing table in this file

Comment thread policy/slots_test.go Outdated
assert.Contains(t, err.Error(), `["a-first" "z-last"]`)
}

func TestSlotFillDepth(t *testing.T) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

most of this is already under test, I think

@rishiz27
rishiz27 requested a review from asvoboda November 6, 2026 17:26
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