Skip to content

fix(safe-outputs): add MCE1 egress context validation to 10 handlers that hard-failed on scheduled runs - #49060

Merged
pelikhan merged 6 commits into
mainfrom
copilot/deep-report-fix-soft-skip-vs-hard-fail
Jul 30, 2026
Merged

fix(safe-outputs): add MCE1 egress context validation to 10 handlers that hard-failed on scheduled runs#49060
pelikhan merged 6 commits into
mainfrom
copilot/deep-report-fix-soft-skip-vs-hard-fail

Conversation

Copilot AI commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

update_pull_request, update_issue, and add_comment had MCE1 egress validation (context checked before writing to NDJSON), but 10 other tools targeting triggering entities fell through to defaultHandler — writing to NDJSON and hard-failing at process_safe_outputs execution time when no PR/issue/discussion context existed (e.g. scheduled runs).

Changes

safe_outputs_handlers.cjs

  • Adds createTriggeringContextHandler factory following the existing MCE1 pattern
  • Creates 10 new handlers: closePullRequestHandler, mergePullRequestHandler, markPullRequestAsReadyForReviewHandler, addReviewerHandler, replyToPullRequestReviewCommentHandler, closeIssueHandler, addLabelsHandler, removeLabelsHandler, updateDiscussionHandler, closeDiscussionHandler
  • Bypasses validation when an explicit target number is provided; gates on triggering context only when the handler would auto-resolve it
// Before: schedule run → writes NDJSON → hard-fail at process_safe_outputs
//   {success: false, error: "No pull_request_number provided and not in pull request context"}

// After: schedule run → immediate MCP error response, no NDJSON write
const result = handlers.closePullRequestHandler({});
// result.isError === true
// result.content[0].text → {result: "error", error: "close_pull_request requires a pull request context but the workflow is running on a \"schedule\" event. ..."}

// Explicit number → bypasses context check, proceeds normally
const result = handlers.closePullRequestHandler({ pull_request_number: 5 });
// result → {result: "success", ...}

safe_outputs_tools_loader.cjs

  • Registers all 10 new handlers in attachHandlers() handlerMap

safe_outputs_handlers.test.cjs

  • Adds 40 unit tests covering: schedule/push event rejection, explicit number bypass, and valid context acceptance for each handler

Run: https://github.com/github/gh-aw/actions/runs/30523835792

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 4.89 AIC · ⌖ 7.33 AIC · ⊞ 8.7K ·
Comment /souschef to run again


Warning

threat detection engine error
The threat detection engine encountered an error and could not complete analysis. This is a tooling failure, not a security finding.

Details

The threat detection engine failed to produce results.

Review the workflow run logs for details.

Run: https://github.com/github/gh-aw/actions/runs/30531795286

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 9.62 AIC · ⊞ 8.7K ·
Comment /souschef to run again

…vent hard-fail on scheduled runs

Adds MCE1 egress validation to close_pull_request, merge_pull_request,
mark_pull_request_as_ready_for_review, add_reviewer,
reply_to_pull_request_review_comment, close_issue, add_labels,
remove_labels, update_discussion, and close_discussion handlers.

When a tool is called without an explicit target number (e.g., no
pull_request_number) on a scheduled/push run that has no triggering
PR/issue/discussion context, the handler now returns an actionable
MCP error response immediately instead of writing to NDJSON and
hard-failing during process_safe_outputs execution.

Introduces createTriggeringContextHandler factory for DRY handler
creation and registers all 10 new handlers in attachHandlers().

Adds 40 unit tests covering: schedule/push context rejection, explicit
number bypass, and valid context acceptance for each handler.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix soft-skip vs hard-fail inconsistency in safe-outputs handler fix(safe-outputs): add MCE1 egress context validation to 10 handlers that hard-failed on scheduled runs Jul 30, 2026
Copilot AI requested a review from pelikhan July 30, 2026 06:44
@pelikhan
pelikhan marked this pull request as ready for review July 30, 2026 06:46
Copilot AI review requested due to automatic review settings July 30, 2026 06:46

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 early triggering-context validation for ten safe-output handlers to prevent downstream failures.

Changes:

  • Adds shared PR, issue, and discussion context validation.
  • Registers the new handlers.
  • Adds unit coverage for rejection, bypass, and valid-context paths.
Show a summary per file
File Description
actions/setup/js/safe_outputs_handlers.cjs Implements context-aware handlers.
actions/setup/js/safe_outputs_tools_loader.cjs Registers the handlers.
actions/setup/js/safe_outputs_handlers.test.cjs Tests handler behavior.

Review details

Tip

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

Comments suppressed due to low confidence (2)

actions/setup/js/safe_outputs_handlers.cjs:2359

  • These checks establish context from the event name alone, without verifying that the payload contains the entity number downstream handlers need. For example, workflow_dispatch can override event_name to pull_request while omitting event_payload; this branch accepts the call and writes NDJSON, then processing still fails because no PR number exists. Require the corresponding pull_request.number, issue.number, or discussion.number in addition to the event type.
          let hasContext;
          if (contextType === "pr") {
            hasContext = PR_EVENT_NAMES.has(effectiveEventName) || isIssueCommentOnPR;
          } else if (contextType === "issue") {
            hasContext = effectiveEventName === "issues" || (effectiveEventName === "issue_comment" && !isIssueCommentOnPR);

actions/setup/js/safe_outputs_handlers.cjs:2337

  • Checking only for non-null values treats "" or whitespace as an explicit number. Several affected schemas allow arbitrary strings for number fields, so such input bypasses context validation, is appended, and fails later during number parsing—the hard-failure path this change is intended to prevent. Reuse the existing helper, which rejects blank explicit targets.
      const hasExplicitNumber = explicitNumberFields.some(field => args?.[field] != null);
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Medium

Comment on lines +2333 to +2337
const createTriggeringContextHandler = ({ toolName, explicitNumberFields, contextType, buildErrorMessage }) => {
return args => {
// If the caller supplied an explicit target number, skip context validation.
// The downstream execution handler will resolve the number normally.
const hasExplicitNumber = explicitNumberFields.some(field => args?.[field] != null);
@github-actions

Copy link
Copy Markdown
Contributor

Triage Summary

  • Category: bug
  • Risk: high
  • Priority Score: 72/100 (impact 38 + urgency 22 + quality 12)
  • Recommended Action: fast_track

Fixes hard-fail on scheduled runs across 10 safe-output handlers lacking MCE1 egress validation. Large diff (639 additions), not draft — recommend expedited review.

Generated by 🔧 PR Triage Agent · auto · 54.9 AIC · ⌖ 5.64 AIC · ⊞ 7.9K ·

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, address unresolved review feedback if any, and rerun checks once the branch is up to date.

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 4.89 AIC · ⌖ 7.33 AIC · ⊞ 8.7K ·
Comment /souschef to run again

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

@copilot run pr-finisher skill

Addressed in commit 1114522. createTriggeringContextHandler now reads getSafeOutputsToolConfig(config, toolName).target and wraps the context-check block with if (effectiveTarget === "triggering"), matching the pattern in updateIssueHandler and updatePullRequestHandler. With target: "*" or a fixed number, the factory skips context validation entirely and delegates to defaultHandler — wildcard enforcement is handled downstream by validateWildcardTargetRequirement. Five new tests cover these bypass paths.

Copilot AI commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, address unresolved review feedback if any, and rerun checks once the branch is up to date.

...

The unresolved review feedback has been addressed (commit 1114522). createTriggeringContextHandler now reads getSafeOutputsToolConfig(config, toolName).target and only runs context validation when effectiveTarget === "triggering". With target: "*" or a fixed number, the factory skips context validation entirely and delegates to defaultHandler — wildcard enforcement is handled downstream by validateWildcardTargetRequirement. Five additional tests cover these bypass paths.

Local validation results:

  • ✅ Reviews — the copilot-pull-request-reviewer thread is outdated (fix applied in 1114522); no actionable unresolved threads remain
  • ✅ Checks (local) — make fmt and all 229 JS tests + full Go test suite pass
  • ❓ Checks (CI) — stale after agent push; needs human re-trigger
  • ✅ Mergeable — PR is open, not draft, no conflicts

Hand-off: CI must be re-triggered by a maintainer (close/reopen PR, workflow_dispatch, or push) before merge.

Copilot AI requested a review from gh-aw-bot July 30, 2026 08:09
@gh-aw-bot

Copy link
Copy Markdown
Collaborator

Warning

threat detection engine error
The threat detection engine encountered an error and could not complete analysis. This is a tooling failure, not a security finding.

Details

The threat detection engine failed to produce results.

Review the workflow run logs for details.

@copilot please run the skill, address unresolved review feedback if any, and rerun checks once the branch is up to date.

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 9.62 AIC · ⊞ 8.7K ·
Comment /souschef to run again

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

[!WARNING]
threat detection engine error
The threat detection engine encountered an error and could not complete analysis. This is a tooling failure, not a security finding....

All review feedback was already addressed in commit 1114522 (the copilot-pull-request-reviewer thread is outdated — the code at those lines now includes if (effectiveTarget === "triggering") target gating).

The CI failure in run 30531795286 is the "PR Sous Chef" workflow on main, not a check on this PR branch. The two errors there (ERR_API: update pull request #49070/#49073 failed) are API-level failures unrelated to this PR's changes. The threat detection failure is a tooling error explicitly flagged in that run's summary as non-security.

This pass also committed the recompile output (242 lock files + SKILL.md) that were produced by the merge with main but not yet staged.

Local validation:

  • ✅ Reviews — the outdated copilot-pull-request-reviewer thread was addressed in 1114522; no actionable unresolved threads remain
  • ✅ Checks (local) — make fmt, make recompile (266/266 compiled), and all 229 JS tests pass
  • ❓ Checks (CI) — stale after agent push; needs human re-trigger
  • ✅ Mergeable — PR is open, not draft, no conflicts

Hand-off: CI must be re-triggered by a maintainer (close/reopen PR, workflow_dispatch, or push) before merge.

@pelikhan
pelikhan merged commit 6e66359 into main Jul 30, 2026
8 checks passed
@pelikhan
pelikhan deleted the copilot/deep-report-fix-soft-skip-vs-hard-fail branch July 30, 2026 10:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[deep-report] Fix soft-skip vs hard-fail inconsistency in safe-outputs handler for scheduled/no-trigger-context runs (PR Sous Chef pattern)

4 participants