Skip to content

Add SEC-006 conformance coverage for E009/E010 in safe-output processor paths - #47003

Merged
pelikhan merged 5 commits into
mainfrom
copilot/sec-006-fix-error-code-references
Jul 21, 2026
Merged

Add SEC-006 conformance coverage for E009/E010 in safe-output processor paths#47003
pelikhan merged 5 commits into
mainfrom
copilot/sec-006-fix-error-code-references

Conversation

Copilot AI commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Safe Outputs spec v1.26.0 requires processor-visible catalog coverage for E009 (CONFIG_HASH_MISMATCH) and E010 (RATE_LIMIT_EXCEEDED). The processor currently referenced E001E008 only, leaving hash-mismatch and rate-limit exhaustion paths without the standardized machine-readable codes expected by conformance checks and downstream consumers.

  • Error catalog extension (actions/setup/js/error_codes.cjs)

    • Added exported constants for:
      • SAFE_OUTPUT_E009 / CONFIG_HASH_MISMATCH
      • SAFE_OUTPUT_E010 / RATE_LIMIT_EXCEEDED
  • E009 on config/hash verification failure (check_workflow_timestamp_api.cjs)

    • Updated stale/unverifiable workflow lock hash failure paths to include E009 CONFIG_HASH_MISMATCH in the failure message emitted via core.setFailed(...).
    • Keeps existing failure semantics while making the outcome spec-addressable.
  • E010 on rate-limit retry exhaustion (error_recovery.cjs)

    • Added explicit rate-limit classification helper for 429 / secondary-limit signals.
    • On retry exhaustion for rate-limit errors (with retry budget ≥ 3), emits E010 RATE_LIMIT_EXCEEDED through the standardized enhanced error path.
    • Expanded transient detection to include "Too Many Requests" so 429-text errors follow retry flow.
  • Focused unit test updates

    • error_codes.test.cjs: validates export presence/value for E009/E010 + named codes.
    • check_workflow_timestamp_api.test.cjs: asserts E009/CONFIG_HASH_MISMATCH is present on hash mismatch failure.
    • error_recovery.test.cjs: covers E010 emission when 429 persists through 3 retries.
throw enhanceError(error, {
  operation: operationName,
  maxRetries: fullConfig.maxRetries,
  retryable: true,
  code: `${SAFE_OUTPUT_E010} ${RATE_LIMIT_EXCEEDED}`,
  suggestion: "RATE_LIMIT_EXCEEDED: GitHub API rate limit persisted after 3 retries.",
});

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

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • pi.dev

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "pi.dev"

See Network Configuration for more information.

Generated by 👨‍🍳 PR Sous Chef · 12.4 AIC · ⌖ 6.12 AIC · ⊞ 5.5K ·
Comment /souschef to run again

@github-actions

Copy link
Copy Markdown
Contributor

PR Triage

Field Value
Category bug
Risk low
Score 38/100
Breakdown impact:12 · urgency:16 · quality:10
Action defer

WIP draft — no committed files yet. Copilot check in progress. Fixes E009/E010 error code references in processor handlers. Defer until CI and files land.

Run §29809051050

Generated by 🔧 PR Triage Agent · 59.3 AIC · ⌖ 5.53 AIC · ⊞ 5.6K ·

Copilot AI changed the title [WIP] Fix processor handlers to reference E009/E010 error codes Add SEC-006 conformance coverage for E009/E010 in safe-output processor paths Jul 21, 2026
Copilot AI requested a review from pelikhan July 21, 2026 07:13
@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot apply changes

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@pelikhan
pelikhan marked this pull request as ready for review July 21, 2026 07:57
Copilot AI review requested due to automatic review settings July 21, 2026 07:57
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@copilot apply changes

Applied the requested updates in commit 28e50db.

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 SEC-006 coverage for Safe Outputs error codes E009 and E010.

Changes:

  • Extends the error-code catalog.
  • Adds E009 to hash-verification failures.
  • Adds E010 rate-limit exhaustion handling and tests.
Show a summary per file
File Description
actions/setup/js/error_codes.cjs Defines E009/E010 constants.
actions/setup/js/error_codes.test.cjs Tests new constants.
actions/setup/js/check_workflow_timestamp_api.cjs Emits E009 for hash failures.
actions/setup/js/check_workflow_timestamp_api.test.cjs Verifies E009 failures.
actions/setup/js/error_recovery.cjs Classifies and reports exhausted rate limits.
actions/setup/js/error_recovery.test.cjs Tests E010 retry 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/error_recovery.cjs:242

  • This checks E010 only on the configured final attempt, not after the mandated third retry. RATE_LIMIT_RETRY_CONFIG.maxRetries is 5, so production callers using it make two extra attempts and emit E010 after five retries while the message still says three. Fail rate-limit errors when attempt reaches 3 (or cap rate-limit retry budgets to 3) to satisfy the linked specification.
        // E010 applies only when retry budget is at least 3 retries.
        const hasEnoughRetriesForE010 = fullConfig.maxRetries >= 3;
        if (hasEnoughRetriesForE010 && isRateLimitError(error)) {

actions/setup/js/error_recovery.cjs:249

  • The E010 error omits the rate-limit reset time. Safe Outputs §9.5 requires E010 details to include X-RateLimit-Reset, but the context passed here contains neither that header nor an equivalent timestamp, so downstream consumers cannot determine when the quota resets. Extract the response header and include it in the standardized error details.
          throw enhanceError(error, {
            operation: operationName,
            attempt: attempt + 1,
            maxRetries: fullConfig.maxRetries,
            retryable: true,
            code: `${SAFE_OUTPUT_E010} ${RATE_LIMIT_EXCEEDED}`,
            suggestion: "RATE_LIMIT_EXCEEDED: GitHub API rate limit persisted after 3 retries.",
  • Files reviewed: 6/6 changed files
  • Comments generated: 1
  • Review effort level: Medium

"rate limit", // GitHub API rate limiting
"secondary rate limit", // GitHub secondary rate limits
"abuse detection", // GitHub abuse detection
...RATE_LIMIT_INDICATORS, // GitHub rate limiting signals (including HTTP 429 text)
@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot please run the pr-finisher skill, update the branch, address this unresolved review thread, and rerun checks once done:

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • pi.dev

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "pi.dev"

See Network Configuration for more information.

Generated by 👨‍🍳 PR Sous Chef · 12.4 AIC · ⌖ 6.12 AIC · ⊞ 5.5K ·
Comment /souschef to run again

Copilot AI commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please run the pr-finisher skill, update the branch, address this unresolved review thread, and rerun checks once done:

I've made the fix locally (commit dd6995e) but am unable to push due to a 403 permission error (gh-aw-bot lacks write access to this branch). Here's a summary of what was done:

Fix in actions/setup/js/error_recovery.cjs — added isRateLimitError(error) check at the top of isTransientError so Octokit-style errors with status: 429 and a non-descriptive message (e.g. "Request failed") are correctly identified as transient and enter the retry flow:

// Status-based rate-limit detection handles cases where the message text is
// not descriptive enough (e.g. Octokit errors with status 429 and a generic
// "Request failed" message). Must be checked before the text patterns.
if (isRateLimitError(error)) {
  return true;
}

Tests added in actions/setup/js/error_recovery.test.cjs:

  1. isTransientError — asserts { status: 429, message: "Request failed" } returns true
  2. withRetry — asserts E010 is emitted when a status-only 429 persists through 3 retries (operation called 4 times)

All 51 error_recovery tests pass locally. A maintainer needs to push the pending local commit to get CI re-triggered.

Copilot AI requested a review from gh-aw-bot July 21, 2026 09:27
@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot apply fix #47003 (comment)

…add test coverage

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

Copilot AI commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@copilot apply fix #47003 (comment)

Fixed in the latest commit. isRateLimitError(error) is now called at the top of isTransientError, so Octokit errors with status: 429 and a generic message like "Request failed" are correctly classified as transient, retried, and emit E010 on exhaustion. Added two tests to cover this: one for isTransientError returning true for status-only 429, and one for withRetry emitting E010 after 3 retries.

@pelikhan
pelikhan merged commit 9b8d872 into main Jul 21, 2026
8 checks passed
@pelikhan
pelikhan deleted the copilot/sec-006-fix-error-code-references branch July 21, 2026 11:48
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.83.0

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.

[Safe Outputs Conformance] SEC-006: Processor handlers do not reference E009/E010 error codes from Section 9.5 catalog

4 participants