Skip to content

Scope activation reactions like status-comment targets and compute activation permissions from both target sets#26693

Merged
pelikhan merged 6 commits intomainfrom
copilot/fix-activation-job-403-error-again
Apr 16, 2026
Merged

Scope activation reactions like status-comment targets and compute activation permissions from both target sets#26693
pelikhan merged 6 commits intomainfrom
copilot/fix-activation-job-403-error-again

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 16, 2026

Activation failed on pull_request because the reaction step was treated as required and requested permissions without target-level control. This change adds reaction target scoping (mirroring status-comment) and derives activation permissions from the combined reaction + status-comment target configuration.

  • Reaction config: add target-scoped object form

    • on.reaction now supports object syntax with:
      • type (reaction emoji, default eyes)
      • issues, pull-requests, discussions (boolean target toggles)
    • Keeps scalar reaction forms ("eyes", "+1", 1, etc.) unchanged.
    • Rejects invalid configs where all targets are disabled.
  • Activation reaction condition: honor scoped targets

    • Reaction step condition generation now uses configured reaction targets instead of always including all event groups.
    • Pull request events are excluded when reaction.pull-requests: false, while enabled targets remain active.
  • Activation permissions: compute union of scoped interactions

    • Activation job permission calculation now unions:
      • reaction-required scopes (based on reaction targets + trigger events)
      • status-comment-required scopes (existing target logic)
    • Prevents over-granting and aligns permission requests with configured behavior.
  • Schema and compiler model updates

    • Extended workflow schema for on.reaction object form.
    • Added typed workflow fields for reaction target toggles and wired parsing into parseOnSection.
  • Focused test coverage updates

    • Added/updated tests for:
      • reaction object parsing and validation
      • reaction condition filtering by target
      • activation permission scoping when PR reactions are disabled
on:
  reaction:
    type: rocket
    pull-requests: false
  status-comment:
    issues: true
    pull-requests: false
    discussions: true

In this configuration, activation reaction/status behavior and activation permissions are both derived from these scoped target sets rather than broad defaults.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw GO111MODULE x_amd64/vet git rev-�� --show-toplevel x_amd64/vet /usr/bin/git -json GO111MODULE x_amd64/vet git (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw GO111MODULE 64/bin/go git rev-�� --show-toplevel sh /usr/bin/git "prettier" --chegit GOPROXY 64/bin/go git (http block)
  • https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq [.object.sha, .object.type] | @tsv -bool -buildtags /usr/local/bin/uname -errorsas -ifaceassert -nilfunc uname -rs -stringintconv -tests /usr/bin/git -json Url: https://gitrev-parse 64/bin/go git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE /opt/hostedtoolcache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /usr/bin/git GOINSECURE GOMOD GOMODCACHE git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v5
    • Triggering command: `/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @TSV -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json fix

Agent-Logs-Url: REDACTED x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet` (http block)

  • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @tsv --show-toplevel -tests /usr/bin/git -json GO111MODULE 64/bin/go git rev-�� --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go git (http block)
  • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @tsv --show-toplevel go /usr/bin/git -json GO111MODULE 64/pkg/tool/linu--show-toplevel git rev-�� --show-toplevel 64/pkg/tool/linux_amd64/vet /usr/bin/git -json cfg 64/pkg/tool/linu--show-toplevel git (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v8
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq [.object.sha, .object.type] | @tsv --show-toplevel -main/dist/ripgr-buildtags /usr/bin/git -json GO111MODULE 64/bin/go git rev-�� --show-toplevel entIssues|Status-tests /usr/bin/git -json GO111MODULE x_amd64/vet git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq [.object.sha, .object.type] | @tsv --show-toplevel ache/go/1.25.8/xGO111MODULE /usr/bin/git 7712831/b413/_pkgit GO111MODULE 64/bin/go git rev-�� --show-toplevel go /usr/bin/git V67v/NYj1YtwSnregit GO111MODULE 64/bin/go git (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v9
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv -bool -buildtags 969286/b329/vet.cfg -errorsas -ifaceassert -nilfunc /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -uns�� -unreachable=false /tmp/go-build818969286/b199/vet.cfg /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet "prettier" --chegit sh 64/bin/go /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv -unreachable=false /tmp/go-build818969286/b042/vet.cfg 969286/b353/vet.cfg npx prettier --cgit GOPROXY 64/bin/go /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -uns�� -unreachable=false /tmp/go-build818969286/b217/vet.cfg /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet --check scripts/**/*.js 64/bin/go /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv -unreachable=false /tmp/go-build818969286/b106/vet.cfg 969286/b347/vet.cfg prettier --check 64/bin/go /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -uns�� -unreachable=false /tmp/go-build818969286/b222/vet.cfg /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet --check scripts/**/*.js 64/bin/go /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv -unreachable=false /tmp/go-build818969286/b062/vet.cfg 969286/b315/vet.cfg npx prettier --cgit GOPROXY 64/bin/go /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -uns�� -unreachable=false /tmp/go-build818969286/b216/vet.cfg /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet --check scripts/**/*.js 64/bin/go /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE /opt/hostedtoolcache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /opt/hostedtoolcache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv -unreachable=false /tmp/go-build818969286/b051/vet.cfg 969286/b316/vet.cfg npx prettier --cgit GOPROXY 64/bin/go /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -uns�� -unreachable=false /tmp/go-build818969286/b214/vet.cfg /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet --check scripts/**/*.js 64/bin/go /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE /opt/hostedtoolcache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /opt/hostedtoolcache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv -json cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env celain --ignore-submodules | head -n 10 GO111MODULE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v0.1.2
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq [.object.sha, .object.type] | @tsv -bool -buildtags 969286/b318/vet.cfg -errorsas -ifaceassert -nilfunc /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet -uns�� -unreachable=false /tmp/go-build818969286/b197/vet.cfg /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet "prettier" --chegit sh 64/bin/go /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq [.object.sha, .object.type] | @tsv 2870306/b001/_pkg_.a GO111MODULE 2870306/b001=> GOINSECURE GOMOD GOMODCACHE go env DitT/cJ9AOjQtXPzZr-QkDitT GO111MODULE /opt/hostedtoolcache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq [.object.sha, .object.type] | @tsv -json cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env -json GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq [.object.sha, .object.type] | @tsv -json cfg 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env -json GO111MODULE 64/pkg/tool/linux_amd64/link GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/link (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v0.47.4
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v0.47.4 --jq [.object.sha, .object.type] | @tsv --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go git rev-�� --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go git (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE 64/bin/go GOINSECURE 8c GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq [.object.sha, .object.type] | @tsv GOSUMDB GOWORK 64/bin/go GOINSECURE GOMOD GOMODCACHE go k/gh�� -json GO111MODULE 64/bin/go GOINSECURE GOMOD erignore go (http block)
  • https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq [.object.sha, .object.type] | @tsv -json GO111MODULE 64/bin/go GOINSECURE 8c GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq [.object.sha, .object.type] | @tsv GOSUMDB GOWORK 64/bin/go GOINSECURE GOMOD GOMODCACHE go k/gh�� -json GO111MODULE 64/bin/go GOINSECURE GOMOD erignore go (http block)

If you need me to access, download, or install something from one of these locations, you can either:

@github-actions

This comment has been minimized.

1 similar comment
@github-actions
Copy link
Copy Markdown
Contributor

Hey @Copilot 👋 — great start on fixing the 403 activation-job failure for pull_request triggers! The problem is well-scoped and the root cause analysis in the description is solid.

A few things to address before this is ready for review:

  • No implementation yet — the PR currently has only an "Initial plan" commit with zero file changes. The actual fix (e.g. continue-on-error, permission-gating on the reaction step, or mirroring the status-comment permission model) still needs to land.
  • Add tests — once the fix is in, test coverage for the activation job's reaction step behaviour under pull_request vs pull_request_target events would be valuable.
  • Draft status — keep the [WIP] label/draft state until the implementation is complete, then request a review from the core team.

If you'd like a hand, here's a ready-to-use agent prompt:

Fix the activation job 403 error when triggered by pull_request events.

Context:
- The `add_reaction` step in the activation job fails with 403 on pull_request triggers because the default GITHUB_TOKEN is read-only for that event.
- `@pelikhan` suggested mirroring the permission model used by the status-comment feature.

Tasks:
1. Find how status-comment handles coarser permissions (look in pkg/workflow or the compiled template for status-comment).
2. Apply the same configuration/permission approach to the reaction step in the activation job template.
3. Ensure the reaction step does not fail the entire activation job — add `continue-on-error: true` as a safety net if the permission model cannot be fully determined at compile time.
4. Add or update tests that cover the activation job behaviour under pull_request triggers (no 403, downstream jobs are not skipped).
5. Run `make test` and confirm all checks pass.

Generated by Contribution Check · ● 1.9M ·

Copilot AI changed the title [WIP] Fix activation job failure on pull_request triggers Scope activation reactions like status-comment targets and compute activation permissions from both target sets Apr 16, 2026
Copilot AI requested a review from pelikhan April 16, 2026 17:49
@pelikhan pelikhan marked this pull request as ready for review April 16, 2026 18:12
Copilot AI review requested due to automatic review settings April 16, 2026 18:12
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds target-scoped configuration for on.reaction (mirroring status-comment), updates activation reaction condition generation to honor those targets, and computes activation-job permissions from the union of enabled reaction/status-comment targets to avoid over-granting.

Changes:

  • Extend reaction parsing to support an object form with type + {issues, pull-requests, discussions} toggles (and reject “all disabled”).
  • Generate activation reaction if: conditions using the configured reaction target toggles.
  • Scope activation interaction permissions based on enabled reaction/status-comment targets + detected trigger events; update schema and tests accordingly.
Show a summary per file
File Description
pkg/workflow/reactions.go Adds parseReactionConfig to support scalar + object reaction config with target toggles.
pkg/workflow/reactions_test.go Adds unit tests for reaction object parsing and “all targets disabled” validation.
pkg/workflow/expression_builder.go Introduces BuildReactionConditionForTargets and routes default behavior through it.
pkg/workflow/expressions_test.go Adds test ensuring PR-related events are excluded when PR reactions are disabled.
pkg/workflow/compiler_types.go Extends WorkflowData with reaction target toggle fields.
pkg/workflow/compiler_safe_outputs.go Wires reaction object parsing into parseOnSection and stores target toggles in WorkflowData.
pkg/workflow/compiler_safe_outputs_test.go Updates reaction map test to assert successful parsing + defaults/toggles.
pkg/workflow/compiler_activation_job.go Uses reaction target toggles for reaction step condition and permission computation; adds helpers for defaulting toggles.
pkg/workflow/activation_permissions_scope_test.go Adds coverage for permission/condition behavior when PR reactions are disabled; updates helper-call signatures.
pkg/parser/schemas/main_workflow_schema.json Updates workflow schema to allow on.reaction object form with target toggles.

Copilot's findings

Tip

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

  • Files reviewed: 10/10 changed files
  • Comments generated: 0

@github-actions
Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 80/100

Excellent test quality

Metric Value
New/modified tests analyzed 9
✅ Design tests (behavioral contracts) 9 (100%)
⚠️ Implementation tests (low value) 0 (0%)
Tests with error/edge cases 9 (100%)
Duplicate test clusters 0
Test inflation detected ⚠️ Borderline (compiler_safe_outputs_test.go: +10 added / +4 in prod file = 2.5:1)
🚨 Coding-guideline violations None

Test Classification Details

View All Test Classifications (9 tests)
Test File Classification Issues Detected
TestActivationPermissionsReactionPullRequestsDisabled activation_permissions_scope_test.go ✅ Design None — full E2E compile + lock-file assertion
TestBuildReactionConditionForTargetsExcludesPullRequests expressions_test.go ✅ Design None — tests disabled-target exclusion
TestParseReactionConfigMap reactions_test.go ✅ Design None — asserts all 4 return values
TestParseReactionConfigMapAllTargetsDisabled reactions_test.go ✅ Design None — error-path test
TestParseOnSectionReactionMapFormat (overhauled) compiler_safe_outputs_test.go ✅ Design None — now tests parsed output, not just error
TestAddActivationInteractionPermissionsMapFallsBackOnInvalidOnYAML (signature update) activation_permissions_scope_test.go ✅ Design Cosmetic change only
TestAddActivationInteractionPermissionsMapFallbackRespectsStatusCommentDiscussionsToggle (signature update) activation_permissions_scope_test.go ✅ Design Cosmetic change only
TestAddActivationInteractionPermissionsMapFallbackRespectsStatusCommentIssuesToggle (signature update) activation_permissions_scope_test.go ✅ Design Cosmetic change only
TestAddActivationInteractionPermissionsMapFallbackRespectsStatusCommentPullRequestsToggle (signature update) activation_permissions_scope_test.go ✅ Design Cosmetic change only

Build Tag Check ✅

All four test files carry //go:build !integration on line 1.


Test Inflation — Borderline Note

compiler_safe_outputs_test.go adds 10 lines against compiler_safe_outputs.go's 4 added lines (2.5:1 ratio), technically tripping the 2:1 threshold. However:

  • The test file also has 7 deletions (net addition is only ~3 lines).
  • The changes being exercised span multiple production files (reactions.go +57, compiler_activation_job.go +66).
  • This is a test refactor (an "expect error" test was converted to a proper behavioral assertion), not bloat.

The 10-point inflation penalty is applied per the formula, but this is not a genuine concern.


Test Quality Highlights

TestParseReactionConfigMapAllTargetsDisabled is a strong safety-net test: it asserts that disabling all three targets (issues, pull-requests, discussions simultaneously) is rejected as an error — preventing a silent footgun in workflow configuration.

TestActivationPermissionsReactionPullRequestsDisabled is an end-to-end integration test that compiles a real workflow file and inspects the generated YAML, covering both the condition logic and the permission derivation in one shot. High-value design test.

TestParseOnSectionReactionMapFormat was previously checking that a map-format reaction raised an error (a test that verified the old wrong behavior). The overhaul to assert correct parsing with proper defaults and explicit values is a meaningful improvement.


Language Support

Tests analyzed:

  • 🐹 Go (*_test.go): 9 tests — unit (//go:build !integration)
  • 🟨 JavaScript (*.test.cjs, *.test.js): 0 tests

Verdict

Check passed. 0% of new tests are implementation tests (threshold: 30%). No coding-guideline violations detected. All new tests enforce genuine behavioral contracts around the new reaction-target scoping and permission-union logic.


📖 Understanding Test Classifications

Design Tests (High Value) verify what the system does:

  • Assert on observable outputs, return values, or state changes
  • Cover error paths and boundary conditions
  • Would catch a behavioral regression if deleted
  • Remain valid even after internal refactoring

Implementation Tests (Low Value) verify how the system does it:

  • Assert on internal function calls (mocking internals)
  • Only test the happy path with typical inputs
  • Break during legitimate refactoring even when behavior is correct
  • Give false assurance: they pass even when the system is wrong

Goal: Shift toward tests that describe the system's behavioral contract — the promises it makes to its users and collaborators.

References: §24526383893

🧪 Test quality analysis by Test Quality Sentinel · ● 696.9K ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

✅ Test Quality Sentinel: 80/100. Test quality is excellent — 0% of new tests are implementation tests (threshold: 30%). All 9 new/modified tests enforce behavioral contracts around the new reaction-target scoping and activation permission union logic. No coding-guideline violations.

…ission derivation

Generated by the Design Decision Gate workflow to document the architectural
decisions implicit in PR #26693.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

Commit pushed: 0fb2c37

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions
Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

This PR makes significant changes to core business logic (>100 new lines in pkg/) but does not have a linked Architecture Decision Record (ADR).

AI has analyzed the PR diff and generated a draft ADR to help you get started:

📄 Draft ADR: docs/adr/26693-reaction-target-scoping-and-union-activation-permission-derivation.md

The draft captures the three core decisions in this PR:

  1. Extending on.reaction to support an object form with per-target boolean toggles (issues, pull-requests, discussions) — mirroring on.status-comment
  2. Computing activation permissions as the union of enabled reaction targets and status-comment targets
  3. Suppressing reaction step conditions for disabled targets (fixing the 403 on pull_request events)

It also notes the relationship to ADR-26535 (event-scoped activation permission derivation), which this PR extends.

What to do next

  1. Review the draft ADR committed to your branch
  2. Complete the missing sections — verify the alternatives listed reflect what you actually considered, and add any context the AI couldn't infer
  3. Reference the ADR in this PR body by adding a line such as:

    ADR: ADR-26693: Reaction Target Scoping and Union Activation Permission Derivation

Once an ADR is linked in the PR body, this gate will re-run and verify the implementation matches the decision.

Why ADRs Matter

"AI made me procrastinate on key design decisions. Because refactoring was cheap, I could always say 'I'll deal with this later.' Deferring decisions corroded my ability to think clearly."

ADRs create a searchable, permanent record of why the codebase looks the way it does. Future contributors (and your future self) will thank you.


📋 Michael Nygard ADR Format Reference

An ADR must contain these four sections to be considered complete:

  • Context — What is the problem? What forces are at play?
  • Decision — What did you decide? Why?
  • Alternatives Considered — What else could have been done?
  • Consequences — What are the trade-offs (positive and negative)?

All ADRs are stored in docs/adr/ as Markdown files numbered by PR number (e.g., 26693-reaction-target-scoping-...md for PR #26693).

🔒 This PR cannot merge until an ADR is linked in the PR body.

References: §24526383923

Note

🔒 Integrity filter blocked 1 item

The following item were blocked because they don't meet the GitHub integrity level.

To allow these resources, lower min-integrity in your GitHub frontmatter:

tools:
  github:
    min-integrity: approved  # merged | approved | unapproved | none

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · ● 208.4K ·

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.

bug: activation job fails with 403 on add_reaction step for pull_request triggers

3 participants