Skip to content

Increase default max-patch-size from 1 MB to 4 MB and improve patch-size-exceeded error messages#39118

Merged
pelikhan merged 6 commits into
mainfrom
copilot/increase-max-patch-size
Jun 13, 2026
Merged

Increase default max-patch-size from 1 MB to 4 MB and improve patch-size-exceeded error messages#39118
pelikhan merged 6 commits into
mainfrom
copilot/increase-max-patch-size

Conversation

Copilot AI commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

The 1 MB default for max-patch-size on create-pull-request and push-to-pull-request-branch was too aggressive — workflows that auto-generate lock files or large artifacts would burn AI credits and then fail at the push step. Raises the default to 4 MB and improves the error message shown when the limit is hit.

Changes

  • Go config parsing (safe_outputs_config.go): default injected at YAML parse time changed 1024 → 4096 KB
  • Go handler registry (safe_outputs_handler_registry.go): fallback defaults in both create_pull_request and push_to_pull_request_branch handlers updated
  • JS handlers: default in create_pull_request.cjs and push_to_pull_request_branch.cjs updated
  • Error message (handle_agent_failure.cjs): patch-size-exceeded failure issue now includes a collapsible "📥 Download the oversized patch to inspect or apply manually" section with gh run download instructions, so users can retrieve and inspect (or manually apply) the patch the agent generated — matching the existing instructions in the patch-apply-failure section
  • Tests: updated 4 test files that asserted the old 1024 default; added 2 new tests covering the patch download instructions block (with and without runUrl)
  • Lock files: all 246 .lock.yml workflow files recompiled with the new default
  • Docs/agent instructions: updated all references across docs/, scratchpad/, and .github/aw/ files
# Before: workflows hitting 1.1 MB patches would fail unexpectedly
safe-outputs:
  create-pull-request: null   # was silently capped at 1024 KB

# After: 4 MB cap — still a guardrail, but sane for generated files
safe-outputs:
  create-pull-request: null   # now defaults to 4096 KB

The per-output max-patch-size override still works as before for anyone needing a tighter or larger limit.

Copilot AI and others added 2 commits June 13, 2026 16:37
Co-authored-by: dsyme <7204669+dsyme@users.noreply.github.com>
Co-authored-by: dsyme <7204669+dsyme@users.noreply.github.com>
Copilot AI changed the title [WIP] Increase maximum patch size to 4MB Increase default max-patch-size from 1 MB to 4 MB Jun 13, 2026
Copilot finished work on behalf of dsyme June 13, 2026 17:00
Copilot AI requested a review from dsyme June 13, 2026 17:00
@dsyme

dsyme commented Jun 13, 2026

Copy link
Copy Markdown
Collaborator

Also make all the changes in this comment: #39107 (comment)

@dsyme

dsyme commented Jun 13, 2026

Copy link
Copy Markdown
Collaborator

@copilot Also make all the changes in this comment: #39107 (comment)

…ssage

Co-authored-by: dsyme <7204669+dsyme@users.noreply.github.com>

Copilot AI commented Jun 13, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Also make all the changes in this comment: #39107 (comment)

Done in the latest commit. The patch-size-exceeded error section in the failure issue now includes a collapsible "📥 Download the oversized patch to inspect or apply manually" block with gh run download instructions (when a runUrl is available), matching the existing pattern in the patch-apply-failure section. Tests added to cover both the with-runUrl and without-runUrl cases.

Copilot AI changed the title Increase default max-patch-size from 1 MB to 4 MB Increase default max-patch-size from 1 MB to 4 MB and improve patch-size-exceeded error messages Jun 13, 2026
Copilot finished work on behalf of dsyme June 13, 2026 17:35
@pelikhan pelikhan marked this pull request as ready for review June 13, 2026 17:58
Copilot AI review requested due to automatic review settings June 13, 2026 17:58
@github-actions

github-actions Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

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

This PR raises the default max-patch-size guardrail for safe-output PR operations from 1024 KB (1 MB) to 4096 KB (4 MB) across the Go compiler/config path, JS safe-output handlers, generated workflow lock files, and docs. It also improves the “patch size exceeded” failure context by adding downloadable patch artifact instructions.

Changes:

  • Updated default max-patch-size to 4096 KB across Go config parsing/handler defaults and JS handlers, plus updated tests and docs to match.
  • Enhanced patch-size-exceeded failure output to include a collapsible section with artifact download + manual inspection/apply instructions.
  • Recompiled numerous .lock.yml workflows so embedded handler configs reflect the new default.
Show a summary per file
File Description
scratchpad/safe-output-environment-variables.md Updates env var docs to reflect new default max patch size.
pkg/workflow/safe_outputs_import_test.go Updates test expectation/comment for new default.
pkg/workflow/safe_outputs_handler_registry.go Updates Go-side handler fallback default to 4096 KB.
pkg/workflow/safe_outputs_config.go Updates YAML-parse-time default injection to 4096 KB.
pkg/workflow/patch_size_validation_test.go Updates expected compiled handler config JSON default.
pkg/workflow/compiler_types.go Updates struct field comment to reflect new default.
pkg/workflow/compiler_safe_outputs_config_test.go Updates compiler test for default patch size.
docs/src/content/docs/reference/safe-outputs.md Updates reference docs default from 1024 → 4096.
docs/src/content/docs/reference/safe-outputs-pull-requests.md Updates PR safe-outputs docs default from 1024 → 4096.
docs/src/content/docs/reference/frontmatter-full.md Updates frontmatter docs default from 1024 → 4096.
actions/setup/js/push_to_pull_request_branch.test.cjs Updates JS handler test output for new default.
actions/setup/js/push_to_pull_request_branch.cjs Updates JS handler default to 4096 KB.
actions/setup/js/handle_agent_failure.test.cjs Adds tests for new patch download instructions block.
actions/setup/js/handle_agent_failure.cjs Adds patch download instructions to patch-size-exceeded error context; updates example default.
actions/setup/js/create_pull_request.cjs Updates JS handler default to 4096 KB.
.github/workflows/weekly-safe-outputs-spec-review.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/weekly-editors-health-check.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/weekly-blog-post-writer.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/update-astro.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/unbloat-docs.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/ubuntu-image-analyzer.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/test-create-pr-error-handling.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/technical-doc-writer.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/spec-extractor.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/spec-enforcer.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/slide-deck-maintainer.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/schema-feature-coverage.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/ruflo-backed-task.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/refiner.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/q.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/pr-sous-chef.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/necromancer.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/mergefest.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/linter-miner.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/layout-spec-maintainer.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/jsweep.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/instructions-janitor.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/hourly-ci-cleaner.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/go-logger.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/glossary-maintainer.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/github-mcp-tools-report.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/functional-pragmatist.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/dictation-prompt.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/design-decision-gate.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/dependabot-worker.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/dead-code-remover.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/daily-workflow-updater.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/daily-safe-output-integrator.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/daily-rendering-scripts-verifier.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/daily-doc-updater.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/daily-compiler-threat-spec-optimizer.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/daily-community-attribution.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/daily-caveman-optimizer.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/daily-astrostylelite-markdown-spellcheck.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/craft.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/code-simplifier.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/code-scanning-fixer.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/cloclo.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/ci-coach.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/chaos-pr-bundle-fuzzer.lock.yml Recompiled lock workflow to embed new default (4096).
.github/workflows/avenger.lock.yml Recompiled lock workflow to embed new default (4096).
.github/aw/syntax-agentic.md Updates agentic syntax docs default from 1024 → 4096.
.github/aw/safe-outputs-runtime.md Updates runtime docs default from 1024 → 4096.
.github/aw/safe-outputs-management.md Updates management docs default from 1024 → 4096.
.github/aw/safe-outputs-content.md Updates content docs default from 1024 → 4096.
.changeset/patch-increase-default-max-patch-size-4mb.md Adds changeset entry documenting the default bump.

Copilot's findings

Tip

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

  • Files reviewed: 80/80 changed files
  • Comments generated: 4

Comment on lines 120 to 123
const signedCommits = config.signed_commits !== false;
const commitTitleSuffix = config.commit_title_suffix || "";
const maxSizeKb = config.max_patch_size ? parseInt(String(config.max_patch_size), 10) : 1024;
const maxSizeKb = config.max_patch_size ? parseInt(String(config.max_patch_size), 10) : 4096;
const maxCount = config.max || 0; // 0 means no limit
const expiresHours = config.expires ? parseInt(String(config.expires), 10) : 0;
const maxCount = config.max || 1; // PRs are typically limited to 1
const maxSizeKb = config.max_patch_size ? parseInt(String(config.max_patch_size), 10) : 1024;
const maxSizeKb = config.max_patch_size ? parseInt(String(config.max_patch_size), 10) : 4096;
Comment thread actions/setup/js/handle_agent_failure.test.cjs
Comment thread actions/setup/js/handle_agent_failure.test.cjs

@github-actions github-actions Bot 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.

Skills-Based Review 🧠

Applied /diagnose, /tdd, and /grill-with-docs — commenting with minor cleanup suggestions, no blocking issues.

📋 Key Themes & Highlights

Key Themes

  • Duplicate run-ID extraction (line 803 & 848): the same 6-line runUrl.match() pattern is now duplicated three times in the file. Extracting an extractRunId(runUrl) helper would prevent divergence.
  • Dead ternary (line 829 & 879): ${runUrl ? ... : ""} inside an if (runId) block is always truthy — the else branch is unreachable.
  • Hardcoded YAML example (line 796): 8192 and the default: 4096 comment will become stale on the next default change; the error message already contains the current limit.
  • Inconsistent test coverage (test line 1471): the two new patch-size-exceeded tests don't assert <details> is emitted, while the parallel patch-apply tests do.

Positive Highlights

  • ✅ 4 MB is a much more sensible default — the original 1 MB silently wasted AI credits before failing at the push step.
  • ✅ The default is updated consistently across Go config, Go handler registry, and both JS handlers — no split-brain defaults.
  • ✅ Good use of progressive disclosure (<details>) in the new error-message section.
  • ✅ Tests cover both the runUrl and no-runUrl branches, which are the two real user-facing scenarios.
  • ✅ 246 lock-file recompilations correctly track the default change with zero manual edits required.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 577.3 AIC · ⌖ 13.8 AIC · ⊞ 27.9K

context += yamlSnippet;

// Provide download instructions so the user can inspect what the agent generated
let runId = "";

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.

[/diagnose] The run-ID extraction pattern is duplicated verbatim from the patch-apply section below (line ~848) and again from an existing block at line ~2848. Three copies of the same 6-line runUrl.match(...) routine is a regression-risk: if the URL format ever changes, all three need updating.

💡 Suggested refactor

Extract a small pure helper at the top of the module:

/**
 * Extracts the numeric run ID from a GitHub Actions run URL.
 * `@param` {string} runUrl  e.g. "https://github.com/owner/repo/actions/runs/12345678"
 * `@returns` {string} run ID, or empty string if not found
 */
function extractRunId(runUrl) {
  if (!runUrl) return "";
  const m = runUrl.match(/\/actions\/runs\/(\d+)/);
  return m ? m[1] : "";
}

Then every caller becomes a one-liner:

const runId = extractRunId(runUrl);

This makes the intent obvious, keeps tests focused on one place, and means a URL-format change only touches one function.

git push origin aw/manual-apply
gh pr create --head aw/manual-apply
\`\`\`
${runUrl ? `\nThe patch artifact is available at: [View run and download artifacts](${runUrl})\n` : ""}`;

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.

[/diagnose] The runUrl ? ternary is dead code: we are already inside if (runId), and runId can only be non-empty when runUrl is truthy and the regex matched. The else branch "" is unreachable, making this branch condition misleading.

💡 Simplify to
// Before (inside `if (runId)`, runUrl is always truthy here)
${runUrl ? `\nThe patch artifact is available at: [View run and download artifacts](${runUrl})\n` : ""}

// After
\nThe patch artifact is available at: [View run and download artifacts](${runUrl})\n

Same simplification applies to the parallel block in the patch-apply section (~line 879).

for (const type of affectedTypes) {
const yamlKey = typeToYamlKey[type] || type.replace(/_/g, "-");
yamlSnippet += ` ${yamlKey}:\n max-patch-size: 2048 # Example: double the default limit (in KB, default: 1024)\n`;
yamlSnippet += ` ${yamlKey}:\n max-patch-size: 8192 # Example: double the default limit (in KB, default: 4096)\n`;

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.

[/grill-with-docs] The example value 8192 and comment # Example: double the default limit (in KB, default: 4096) are hardcoded. If the default changes again, this snippet will silently become stale. Consider deriving the suggested value from the actual limit in the error string, which already contains the current limit (e.g. maximum allowed size (4096 KB)).

expect(result).toContain("https://github.com/owner/repo/pull/99");
});

it("includes download instructions with run ID when runUrl is provided for patch size exceeded", () => {

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.

[/tdd] The two new tests for the patch-size-exceeded download block don't assert that a <details> progressive-disclosure block is present, even though the implementation adds one. The parallel patch-apply tests (lines ~1535–1558) do assert <details> — worth adding the same assertion here for consistency and to prevent the disclosure block from being accidentally removed.

@github-actions

Copy link
Copy Markdown
Contributor

@copilot review all comments and address unresolved review feedback. Then refresh the branch and rerun checks.

Generated by 👨‍🍳 PR Sous Chef · 143.8 AIC · ⌖ 1.04 AIC · ⊞ 17.4K ·

@github-actions

github-actions Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions

github-actions Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed for PR #39118: it does not have the 'implementation' label and has only 8 new lines of code in business logic directories (≤100 threshold).

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 80/100 — Excellent

Analyzed 6 test(s): 6 design, 0 implementation, 0 guideline violations.

📊 Metrics & Test Classification (6 tests analyzed)
Metric Value
New/modified tests analyzed 6
✅ Design tests (behavioral contracts) 6 (100%)
⚠️ Implementation tests (low value) 0 (0%)
Tests with error/edge cases 2 (33%)
Duplicate test clusters 0
Test inflation detected No
🚨 Coding-guideline violations 0

Test Classification Details

Test File Classification Issues Detected
includes download instructions with run ID when runUrl is provided for patch size exceeded handle_agent_failure.test.cjs ✅ Design Pure function, 4 assertions on error message output
includes generic download instructions when no runUrl is provided for patch size exceeded handle_agent_failure.test.cjs ✅ Design Includes .not.toContain negative guard; covers the no-runUrl edge case
should default max_patch_size to 4096 KB (modified from 1024 KB) push_to_pull_request_branch.test.cjs ✅ Design Happy-path; @actions/core mock is acceptable external I/O
TestHandlerConfigPatchSize — default patch size row compiler_safe_outputs_config_test.go ✅ Design Constant-propagation update to existing table-driven test
Patch size validation default (max_patch_size:4096) patch_size_validation_test.go ✅ Design Verifies compiled workflow YAML contains correct value
assert.Equal(t, 4096, workflowData.SafeOutputs.MaximumPatchSize, ...) safe_outputs_import_test.go ✅ Design Assertion message present; tests import-merge defaults correctly

Language Support

Tests analyzed:

  • 🐹 Go (*_test.go): 3 modified tests — unit tests only, no new files, no build-tag issues, no mocks
  • 🟨 JavaScript (*.test.cjs): 3 tests — 2 new it() blocks + 1 modified (vitest)

Verdict

Check passed. 0% of new/modified tests are implementation tests (threshold: 30%). All six changes are behavioral contract tests verifying observable outputs.

📖 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: §27474598968

🧪 Test quality analysis by Test Quality Sentinel · 448.7 AIC · ⌖ 19.5 AIC · ⊞ 27.3K ·

@github-actions github-actions Bot 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.

✅ Test Quality Sentinel: 80/100. Test quality is excellent — 0% of new tests are implementation tests (threshold: 30%). All 6 changed tests are behavioral contract tests with clear assertions on observable outputs.

Copilot AI and others added 2 commits June 13, 2026 18:38
…ctRunId helper, test alignment

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

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

Copilot AI commented Jun 13, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Also make all the changes in this comment: #39107 (comment)

Done. The following changes were made in 4c62bd5 (building on the previous download-instructions commit):

  • parsePositiveInteger is now used for max_patch_size in both push_to_pull_request_branch.cjs and create_pull_request.cjs (added the helper to the latter for consistency), so malformed/non-positive values fall back to the default instead of silently passing NaN through comparison.
  • extractRunId(runUrl) helper extracted to deduplicate the three copies of the runUrl.match(/\/actions\/runs\/(\d+)/) pattern.
  • Dead ${runUrl ? … : ""} ternaries removed from both the patch-size-exceeded and patch-apply sections (both were already inside if (runId) guards where runUrl is always truthy).
  • YAML example value is now derived dynamically from the actual limit in the error message rather than hardcoding 8192.
  • New patch-size-exceeded tests updated to use 4096 KB and now assert the <details> progressive-disclosure block is present, matching the parallel patch-apply tests.

@copilot run pr-finisher skill

All review threads addressed in commits 4d67a7a4c62bd5. Local make fmt, make lint, and make test-unit all pass. See summary below — PR is ready for human CI re-trigger and merge.


  • Reviews — all 8 unresolved threads addressed: parsePositiveInteger fixes, extractRunId refactor, dead-code removal, dynamic YAML value, test alignment with <details> assertions.
  • Checks (local)make fmt, make lint, make test-unit all pass.
  • Checks (CI) — stale after agent push; needs human re-trigger. No prior CI failures were observed.
  • Mergeable — PR is open, not draft, no conflicts detected.

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

Copilot AI requested a review from pelikhan June 13, 2026 18:41
@pelikhan pelikhan merged commit 24aab94 into main Jun 13, 2026
37 checks passed
@pelikhan pelikhan deleted the copilot/increase-max-patch-size branch June 13, 2026 20:10
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.

4 participants