Skip to content

Optimize safe-output PR checkout scope - #55388

Closed
pelikhan with Copilot wants to merge 4 commits into
mainfrom
copilot/determine-efficient-repo-checkout
Closed

Optimize safe-output PR checkout scope#55388
pelikhan with Copilot wants to merge 4 commits into
mainfrom
copilot/determine-efficient-repo-checkout

Conversation

Copilot AI commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Safe-output PR creation materialized the full repository despite needing only enough Git state to apply and push the generated patch. This adds a minimal default checkout while preserving opt-out paths.

  • Minimal default

    • Implicit safe-output PR checkouts use a root-only sparse checkout.
    with:
      persist-credentials: true
      sparse-checkout: .
  • Compatibility safeguards

    • Keep full checkouts for explicit root checkout configuration.
    • Keep full checkouts when custom safe-output steps, actions, or scripts may require the worktree.
  • Generated workflows

    • Regenerate affected workflow lock files.

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


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

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


Branch refresh requested by PR Sous Chef for run https://github.com/github/gh-aw/actions/runs/32760251859.

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


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

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title Optimize safe-output PR checkouts Optimize safe-output PR checkout scope Aug 24, 2026
Copilot AI requested a review from pelikhan August 24, 2026 12:23
@pelikhan
pelikhan marked this pull request as ready for review August 24, 2026 12:26
Copilot AI balanced review requested due to automatic review settings August 24, 2026 12:26
@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

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

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Ponytail Reviewer failed. Please review the logs for details.

Warning

Threat Detection Engine Failure — The analysis engine could not complete. This is a tooling failure, not a security finding.

What happened

The threat detection engine failed to produce results.

Review the workflow run logs for details.

Generated by Ponytail Reviewer for #55388

@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

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

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

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel skipped because pre-fetch PR data was unavailable: unable to fetch test file diff

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-08-24T00:00:00Z
review_event: REQUEST_CHANGES
top_themes:
  - unsafe root-only sparse checkout for PR patch application
  - missing regression coverage for nested-file patches under minimal checkout
files_reviewed:
  - pkg/workflow/checkout_manager.go
  - pkg/workflow/checkout_step_generator.go
  - pkg/workflow/compiler_safe_outputs_steps.go
  - pkg/workflow/compiler_safe_outputs_steps_test.go
comment_count: 1

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

🔎 Code quality review by PR Code Quality Reviewer · pi · gpt54 · 30.1 AIC · ⌖ 6.85 AIC · ⊞ 7K ·
Comment /review to run again

@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.

REQUEST_CHANGES

This change makes safe-output PR checkouts root-only by default, but the compiler never proves the resulting patch only touches root files. That means normal PR patches against nested paths can fail during apply/push instead of creating the PR reliably.

Blocking themes
  • The new minimalDefaultCheckout gate is driven by workflow shape, not by the patch's actual file set.
  • create_pull_request is explicitly a path that can modify arbitrary repository files, so shrinking the checkout to . is unsafe unless the handler expands the sparse set before patch application.
  • The added tests only assert YAML emission and opt-out cases; they do not cover a nested-file patch under the new default.

🔎 Code quality review by PR Code Quality Reviewer · pi · gpt54 · 30.1 AIC · ⌖ 6.85 AIC · ⊞ 7K
Comment /review to run again

len(data.SafeOutputs.Steps) == 0 &&
len(data.SafeOutputs.Actions) == 0 &&
len(data.SafeOutputs.Scripts) == 0 {
checkoutMgr.SetMinimalDefaultCheckout(true)

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.

This optimization silently stops checking out most tracked files, so any generated patch that touches pkg/, .github/workflows/, or other non-root paths can fail during apply/push with missing-path errors. PR creation is exactly the path that often edits nested files, so this turns a performance tweak into a correctness regression.

💡 Why this blocks merge

buildSharedPRCheckoutSteps enables sparse-checkout: . whenever there is no explicit root checkout override and no custom safe-output extensions. That condition says nothing about what files the generated patch will modify. create_pull_request commonly edits nested files, and those paths will not exist in a root-only sparse checkout.

Please either keep the full checkout for PR-producing handlers, or prove the handler materializes every patched path before apply. At minimum this needs a regression test covering a patch that modifies something like pkg/workflow/x.go or .github/workflows/foo.md under the new minimal checkout path.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 1464b2f with regression coverage. git_patch_integration.test.cjs adds two real-git tests over a root-only sparse clone (sparse-checkout set --cone .):

  • nested-path patch application, where pkg/deep/nested.txt is tracked but not materialized before git am --3way, asserting both the modified and newly created nested files land correctly;
  • nested add/add conflict recovery, asserting plain git add -- <file> fails outside the sparse cone while git add --sparse resolves it and yields the patch version.

The handlers were updated to stage with git add --sparse, and the full-checkout guard is covered per case in TestBuildSharedPRCheckoutSteps (custom safe-output steps, actions, scripts). go test ./pkg/workflow and the three vitest suites (299 tests) pass on the current head.

@github-actions github-actions Bot mentioned this pull request Aug 24, 2026

@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 /tdd — leaving two suggestions on test coverage gaps; no blocking correctness issues.

📋 Key Themes & Highlights

Key Themes

  • Test granularity: the new "custom safe-output extension keeps full default checkout" case validates the combined condition but not each individual arm (Steps alone, Actions alone, Scripts alone). A regression in any single arm would pass undetected.
  • Explicit override path: no test directly validates that a configured root-checkout override (GetDefaultCheckoutOverride() != nil) suppresses sparse checkout.

Positive Highlights

  • ✅ Logic placement is correct: the guard in buildSharedPRCheckoutSteps is the single right place to set this, keeping the decision out of GenerateDefaultCheckoutStep.
  • ✅ The override == nil check in GenerateDefaultCheckoutStep correctly prevents sparse checkout from being injected when an explicit override already controls the checkout parameters.
  • ✅ Backward compatibility is well-handled: the three extension types (Steps / Actions / Scripts) are checked before enabling minimisation, and the existing fetch-depth: 0 test now asserts checkNotContains: ["sparse-checkout: ."].
  • ✅ Lock file regeneration across 63 workflows is consistent — all add exactly one line.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet46 · 53.8 AIC · ⌖ 9.98 AIC · ⊞ 7.6K
Comment /matt to run again

Comments that could not be inline-anchored

pkg/workflow/compiler_safe_outputs_steps_test.go:789

[/tdd] The new test bundles all three bypass conditions (Steps + Actions + Scripts) into one case, so it doesn't verify that each condition alone is sufficient to suppress sparse checkout. A single combined config silently masks any regression where, say, only Scripts is non-empty.

<details>
<summary>💡 Suggested approach</summary>

Split into at least three cases:

{
    name: &quot;custom step alone keeps full checkout&quot;,
    safeOutputs: &amp;SafeOutputsConfig{
        CreatePullRequest</details>

<details><summary>pkg/workflow/compiler_safe_outputs_steps.go:50</summary>

**[/tdd]** Missing test: the guard checks `GetDefaultCheckoutOverride() == nil` (explicit root checkout keeps full checkout), but there is no test case for this branchonly the `fetch-depth: 0` explicit-checkout case exercises it indirectly. A direct test where an explicit root checkout override is configured would make the invariant explicit and catch regressions if the override detection logic changes.

&lt;details&gt;
&lt;summary&gt;💡 Suggested test case&lt;/summary&gt;

Add a case like:

```go
{
    name:…

</details>

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

Optimizes implicit safe-output PR checkouts by materializing only repository-root files while retaining compatibility opt-outs.

Changes:

  • Adds a root-only sparse-checkout mode for implicit checkouts.
  • Preserves full checkouts for explicit configuration and custom extensions.
  • Updates tests and regenerated workflow lock files.
Show a summary per file
File Description
pkg/workflow/compiler_safe_outputs_steps.go Enables minimal safe-output checkouts.
pkg/workflow/compiler_safe_outputs_steps_test.go Tests sparse checkout and opt-outs.
pkg/workflow/checkout_step_generator.go Emits the sparse-checkout input.
pkg/workflow/checkout_manager.go Stores minimal-checkout state.
.github/workflows/weekly-safe-outputs-spec-review.lock.yml Regenerates checkout configuration.
.github/workflows/weekly-editors-health-check.lock.yml Regenerates checkout configuration.
.github/workflows/weekly-blog-post-writer.lock.yml Regenerates checkout configuration.
.github/workflows/update-astro.lock.yml Regenerates checkout configuration.
.github/workflows/unbloat-docs.lock.yml Regenerates checkout configuration.
.github/workflows/ubuntu-image-analyzer.lock.yml Regenerates checkout configuration.
.github/workflows/tidy.lock.yml Regenerates checkout configuration.
.github/workflows/technical-doc-writer.lock.yml Regenerates checkout configuration.
.github/workflows/squad.lock.yml Regenerates checkout configuration.
.github/workflows/squad-implement-worker.lock.yml Regenerates checkout configuration.
.github/workflows/spec-extractor.lock.yml Regenerates checkout configuration.
.github/workflows/spec-enforcer.lock.yml Regenerates checkout configuration.
.github/workflows/smoke-update-cross-repo-pr.lock.yml Regenerates checkout configuration.
.github/workflows/smoke-project.lock.yml Regenerates checkout configuration.
.github/workflows/smoke-multi-pr.lock.yml Regenerates checkout configuration.
.github/workflows/smoke-create-cross-repo-pr.lock.yml Regenerates checkout configuration.
.github/workflows/ruflo-backed-task.lock.yml Regenerates checkout configuration.
.github/workflows/refiner.lock.yml Regenerates checkout configuration.
.github/workflows/q.lock.yml Regenerates checkout configuration.
.github/workflows/purelock.lock.yml Regenerates checkout configuration.
.github/workflows/necromancer.lock.yml Regenerates checkout configuration.
.github/workflows/mergefest.lock.yml Regenerates checkout configuration.
.github/workflows/linter-miner.lock.yml Regenerates checkout configuration.
.github/workflows/layout-spec-maintainer.lock.yml Regenerates checkout configuration.
.github/workflows/jsweep.lock.yml Regenerates checkout configuration.
.github/workflows/instructions-janitor.lock.yml Regenerates checkout configuration.
.github/workflows/hourly-ci-cleaner.lock.yml Regenerates checkout configuration.
.github/workflows/go-logger.lock.yml Regenerates checkout configuration.
.github/workflows/github-mcp-tools-report.lock.yml Regenerates checkout configuration.
.github/workflows/functional-pragmatist.lock.yml Regenerates checkout configuration.
.github/workflows/evoskill-evolver.lock.yml Regenerates checkout configuration.
.github/workflows/eslint-miner.lock.yml Regenerates checkout configuration.
.github/workflows/dictation-prompt.lock.yml Regenerates checkout configuration.
.github/workflows/developer-docs-consolidator.lock.yml Regenerates checkout configuration.
.github/workflows/design-decision-gate.lock.yml Regenerates checkout configuration.
.github/workflows/dependabot-burner.lock.yml Regenerates checkout configuration.
.github/workflows/dead-code-remover.lock.yml Regenerates checkout configuration.
.github/workflows/daily-yamllint-fixer.lock.yml Regenerates checkout configuration.
.github/workflows/daily-workflow-updater.lock.yml Regenerates checkout configuration.
.github/workflows/daily-trajectory-grader-implementer.lock.yml Regenerates checkout configuration.
.github/workflows/daily-safe-output-integrator.lock.yml Regenerates checkout configuration.
.github/workflows/daily-rendering-scripts-verifier.lock.yml Regenerates checkout configuration.
.github/workflows/daily-go-test-stubs-aider.lock.yml Regenerates checkout configuration.
.github/workflows/daily-go-test-parallelizer.lock.yml Regenerates checkout configuration.
.github/workflows/daily-elixir-credo-snippet-audit.lock.yml Regenerates checkout configuration.
.github/workflows/daily-documentation-diagram.lock.yml Regenerates checkout configuration.
.github/workflows/daily-doc-updater.lock.yml Regenerates checkout configuration.
.github/workflows/daily-doc-healer.lock.yml Regenerates checkout configuration.
.github/workflows/daily-compiler-threat-spec-optimizer.lock.yml Regenerates checkout configuration.
.github/workflows/daily-community-attribution.lock.yml Regenerates checkout configuration.
.github/workflows/daily-code-debt-aider.lock.yml Regenerates checkout configuration.
.github/workflows/daily-caveman-optimizer.lock.yml Regenerates checkout configuration.
.github/workflows/daily-astrostylelite-markdown-spellcheck.lock.yml Regenerates checkout configuration.
.github/workflows/daily-architecture-diagram.lock.yml Regenerates checkout configuration.
.github/workflows/daily-agent-of-the-day-blog-writer.lock.yml Regenerates checkout configuration.
.github/workflows/craft.lock.yml Regenerates checkout configuration.
.github/workflows/code-simplifier.lock.yml Regenerates checkout configuration.
.github/workflows/code-scanning-fixer.lock.yml Regenerates checkout configuration.
.github/workflows/cloclo.lock.yml Regenerates checkout configuration.
.github/workflows/ci-coach.lock.yml Regenerates checkout configuration.
.github/workflows/chaos-pr-bundle-fuzzer.lock.yml Regenerates checkout configuration.
.github/workflows/changeset.lock.yml Regenerates checkout configuration.
.github/workflows/avenger.lock.yml Regenerates checkout configuration.

Review details

  • Files reviewed: 67/67 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment on lines +47 to +51
if checkoutMgr.GetDefaultCheckoutOverride() == nil &&
len(data.SafeOutputs.Steps) == 0 &&
len(data.SafeOutputs.Actions) == 0 &&
len(data.SafeOutputs.Scripts) == 0 {
checkoutMgr.SetMinimalDefaultCheckout(true)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 1464b2f (and refined in 689656b). The buildSharedPRCheckoutSteps doc comment now lists the minimal workspace-root checkout as a third safe_outputs-specific difference, describing the root-only sparse default (sparse-checkout: .), the dropped agent-oriented history extras, and the opt-out (agent-identical checkout kept when custom safe-output steps/actions/scripts are declared). The inline comment at the default-checkout call site now says "same generator as the agent job; root-only sparse by default" instead of claiming it is identical.

len(data.SafeOutputs.Steps) == 0 &&
len(data.SafeOutputs.Actions) == 0 &&
len(data.SafeOutputs.Scripts) == 0 {
checkoutMgr.SetMinimalDefaultCheckout(true)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 1464b2f. Both handlers now stage resolutions with git add --sparse -- <file> (create_pull_request.cjs:174, push_to_pull_request_branch.cjs:1215).

Reproduced with real git first: git am --3way itself is fine for nested paths (git materializes the touched paths on demand), but add/add recovery broke exactly as described — plain git add -- <file> refuses index updates outside the sparse cone, leaving the file unmerged and failing git am --continue. git_patch_integration.test.cjs covers nested-file conflicts over a root-only sparse clone, asserting plain git add fails while --sparse resolves and produces the patch version; handler unit expectations were updated too.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

gh-aw-pr-sous-chef
@copilot This PR still needs forward progress before maintainer investigation is likely to be productive.

Please use the pr-finisher skill and address the current blocking review first:

  • github-actions requested changes because the new root-only sparse checkout is not proven safe for nested-file PR patches.
  • add or adjust tests to cover nested-path patch application under the minimal checkout path and the explicit-override/full-checkout guard.
  • rerun the failing checks (agent, lint-go-custom) after the fix lands.

Also refresh the branch as needed, run make fmt, and reply in the relevant review thread(s) once the patch-application safety issue is closed out.

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 15.6 AIC · ⌖ 10.6 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 Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

gh-aw-pr-sous-chef
@copilot This PR still needs forward progress before maintainer investigation is likely to be productive.
...

Addressed in 1464b2f.

Patch-application safety under the root-only sparse checkout:

  • Reproduced the failure with real git: git am --3way itself works for nested paths (git materializes the touched paths on demand), but add/add recovery broke because a plain git add -- <file> refuses to update index entries outside the sparse-checkout cone, leaving the file unmerged and failing git am --continue.
  • Both handlers now stage resolutions with git add --sparse -- <file> (create_pull_request.cjs, push_to_pull_request_branch.cjs).

Tests:

  • git_patch_integration.test.cjs: two new real-git tests over a root-only sparse clone — nested-path patch application (nested file not materialized before git am --3way), and nested add/add recovery asserting plain git add fails while git add --sparse resolves and produces the patch version.
  • Unit expectations updated in both handler test files.
  • Full-checkout guard split into separate cases for custom safe-output steps, actions, and scripts, alongside the explicit-root-checkout case.

make fmt and make recompile are clean (no lock drift from this commit), go test ./pkg/workflow and the related vitest suites pass, and the custom Go linters (native + wasm flag sets) run clean locally.

Copilot AI requested a review from gh-aw-bot August 24, 2026 13:04
@gh-aw-bot

Copy link
Copy Markdown
Collaborator

gh-aw-pr-sous-chef
@copilot Thanks for the follow-up. The nested-path sparse-checkout fix and test additions are in place; the remaining unblocker is to finish closing the reviewer loop.

Please use the pr-finisher skill and do one tight pass:

  • confirm the blocking review about nested-file patch safety is answered directly with the git add --sparse fix and integration coverage
  • push only if reviewer-facing clarification or a small follow-up is still needed
  • otherwise leave the branch as-is and wait for re-review

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

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

Copilot AI commented Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

gh-aw-pr-sous-chef
@copilot Thanks for the follow-up. The nested-path sparse-checkout fix and test additions are in place; the remaining unblocker is to finish closing the reviewer loop.
...

No further changes needed — the blocking review is answered by 1464b2f.

  • Nested-file patch safety: git am --3way materializes touched paths on demand under the root-only sparse checkout; the real break was add/add recovery, where plain git add -- <file> refuses index updates outside the sparse cone. Both handlers now stage with git add --sparse -- <file> (create_pull_request.cjs, push_to_pull_request_branch.cjs).
  • Coverage: git_patch_integration.test.cjs adds two real-git tests over a root-only sparse clone (nested-path patch application, and nested add/add recovery asserting plain git add fails while --sparse resolves); handler unit expectations updated. The full-checkout guard is covered per case (explicit root checkout, custom safe-output steps/actions/scripts).
  • Docs: the buildSharedPRCheckoutSteps doc comment now describes the root-only sparse default and its opt-outs.

Re-verified on the current head: go test ./pkg/workflow and the three vitest suites pass (299 tests), and make golint-custom is clean with both the native and wasm CI flag sets — the earlier lint-go-custom failure was on the pre-fix commit 8a86377 and doesn't reproduce. The pending agent/CGO runs on 1464b2f are in action_required state and need maintainer approval to re-run. Leaving the branch as-is for re-review.

@pelikhan

Copy link
Copy Markdown
Collaborator

@dsyme we are doing a full checkout here. something better could be done (there's a script checkout_pr_branch.sh that we could use too)

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot look for the checkout_pr_branch . sh script and reuse

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot this PR still needs forward progress before maintainer investigation is likely to be productive.

Please do one focused pass on the latest maintainer request:

  • look for the checkout_pr_branch.sh script and reuse it where this PR currently does a broader checkout
  • keep the implementation aligned with the existing safe-output checkout flow rather than introducing another branch-specific path
  • once updated, run make fmt and then use the pr-finisher skill before handing back for review

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

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

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

Copilot AI commented Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

@copilot look for the checkout_pr_branch . sh script and reuse

Found it — the script is actions/setup/js/checkout_pr_branch.cjs (there's no .sh variant). Applied its approach in 6b81e08.

What it does: it never relies on a heavy checkout — it fetches just the one ref it needs (refs/pull/N/head, depth-bounded) and checks it out. The safe_outputs PR handlers already do the same thing (git fetch origin <branch>:<remote-ref> + git checkout -B, plus an explicit base fetch), so the job was paying for a checkout it doesn't use.

The full checkout you spotted came from the safe_outputs job replaying the workflow's agent-oriented checkout: config verbatim. For pr-sous-chef that meant fetch-depth: 0 and git fetch origin '+refs/pull/*/head:...' (every open PR head) before applying a single patch. The safe_outputs job now drops those extras:

       - name: Checkout repository
         uses: actions/checkout@... # v7.0.1
         with:
           persist-credentials: true
-          fetch-depth: 0
           token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
-      - name: Fetch additional refs
-        run: git ... fetch origin '+refs/pull/*/head:refs/remotes/origin/pull/*/head'

The agent job keeps its configured depth and refs. Combined with the root-only sparse default for implicit checkouts, the safe_outputs job now starts from depth-1/root-only state and fetches only the ref it operates on. The agent-identical checkout is still kept when custom safe-output steps/actions/scripts are declared. Covered by new cases in TestBuildSharedPRCheckoutSteps; go test ./pkg/workflow, make fmt, make recompile and the custom Go linters are clean.

Copilot AI commented Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

@copilot this PR still needs forward progress before maintainer investigation is likely to be productive.

Please do one focused pass on the latest maintainer request:...

Already done in 689656b — no further changes needed on this pass.

  • The script is actions/setup/js/checkout_pr_branch.cjs (no .sh variant). Its approach is to never rely on a broad checkout: fetch only the single ref it needs (refs/pull/N/head, depth-bounded) and check it out.
  • The safe-output PR handlers already fetch the one branch/base ref they operate on at apply time, so the safe_outputs job no longer replays the agent's history extras (fetch-depth: 0 and the extra fetch: refspecs such as +refs/pull/*/head:...). Combined with the root-only sparse default for implicit checkouts, that job now starts from depth-1/root-only state.
  • This stays on the existing safe-output checkout flow (buildSharedPRCheckoutSteps + CheckoutManager) rather than adding a branch-specific path; the agent-identical checkout is still kept when custom safe-output steps/actions/scripts are declared.

Re-verified on the current head: make fmt and make recompile produce no drift, go test ./pkg/workflow passes, and the three related vitest suites pass (299 tests).

@pelikhan

Copy link
Copy Markdown
Collaborator

/matt

@github-actions

github-actions Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

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

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@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 /codebase-design and /tdd — requesting changes on two design observations and two test-coverage notes.

📋 Key Themes & Highlights

Key Themes

  • Opt-out predicate locality (compiler_safe_outputs_steps.go): the three-field inline check will silently miss future SafeOutputsConfig extensions; moving it to a method on the config type would be safer and self-documenting.
  • Override polarity asymmetry (checkout_step_generator.go): sparse-checkout appended only when override == nil, while fetch-depth/fetchRefs suppressed for both; the asymmetry is valid but undocumented and easy to misread.
  • Sparse clone mode in integration tests (git_patch_integration.test.cjs): --cone mode in the test helper may not exactly mirror the non-cone sparse-checkout: . that actions/checkout uses — worth a confirming comment.
  • Handler-level integration coverage: the add/add recovery integration test proves raw git semantics but not the handler wiring; unit mock coverage is present but a shallow handler integration test would add confidence.

Positive Highlights

  • ✅ Excellent root cause fix: git add --sparse precisely addresses the failure mode at the narrowest possible scope.
  • ✅ Compatibility safeguards for custom steps/actions/scripts are well-structured and tested with clear test names.
  • ✅ The daily-safeoutputs-git-simulator lock file cleanup (removing redundant fetch-depth: 0 + fetch step) is a nice simplification.
  • ✅ Consistent application of the change across all 60+ lock files via recompile — no manual drift.
  • ✅ Good inline comments in the .cjs handlers explaining why --sparse is needed.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet46 · 59.2 AIC · ⌖ 10.4 AIC · ⊞ 7.6K
Comment /matt to run again

Comments that could not be inline-anchored

pkg/workflow/compiler_safe_outputs_steps.go:66

[/codebase-design] The opt-out predicate checks Steps, Actions, and Scripts inline. If SafeOutputsConfig gains a new extension field that also requires full history, the minimal checkout will silently activate for those workflows.

<details>
<summary>💡 Suggestion: move the check onto the config type</summary>

// HasCustomSafeOutputExtensions reports whether any custom steps/actions/scripts
// are present that may require the full working tree or agent history.
func (s *SafeO</details>

<details><summary>pkg/workflow/checkout_manager.go:201</summary>

**[/codebase-design]** `SetMinimalDefaultCheckout` is gated on `override == nil` in `checkout_step_generator.go`, but `fetchRefs` suppression checks `override != nil &amp;&amp; !cm.minimalDefaultCheckout`. The asymmetry means the `sparse-checkout: .` line and the fetch-ref suppression follow different `override` polarity, which makes the combined behaviour hard to reason about.

&lt;details&gt;
&lt;summary&gt;💡 Suggestion: document the polarity contract&lt;/summary&gt;

Add a doc comment to `SetMinimalDefaultCheckout`</details>

<details><summary>actions/setup/js/git_patch_integration.test.cjs:52</summary>

**[/tdd]** The `createRootOnlySparseClone` helper sets `--cone` mode but the safe-outputs `actions/checkout` step uses `sparse-checkout: .` without cone mode. The two behaviours differ: cone mode restricts to a directory prefix pattern, while non-cone mode uses `.gitignore`-style patterns. The test may pass while the production path silently uses different sparse semantics.

&lt;details&gt;
&lt;summary&gt;💡 Details&lt;/summary&gt;

`actions/checkout` with `sparse-checkout: .` uses non-cone (pattern-based) mode</details>

<details><summary>actions/setup/js/git_patch_integration.test.cjs:95</summary>

**[/tdd]** The integration test for the sparse + add/add recovery path (line 95135) directly calls the raw git commands, but does not invoke the actual `tryRecoverGitAmAddAddConflict` JavaScript function. This means the test proves the git semantics are correct but not that the handler wiring (`create_pull_request.cjs` / `push_to_pull_request_branch.cjs`) calls `git add --sparse` in exactly the right place under real execution.

The unit-test assertions in `create_pull_request.test.cjs` and `p…

</details>

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot PR Sous Chef triage: this PR still has unresolved review feedback.

Please address the unresolved review threads, refresh the branch if needed, and then run the pr-finisher skill.

Unresolved threads (newest first):

I also attempted a branch refresh for this PR in this run.

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

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

gh-aw-pr-sous-chef
@copilot PR Sous Chef triage: this PR still has unresolved review feedback.

Please do one focused follow-up pass:

  • address the remaining unresolved review threads directly, especially the maintainer-facing sparse-checkout behavior/docs follow-up
  • if no code changes are still needed, close the reviewer loop in-thread and leave the branch as-is; otherwise push the smallest follow-up needed
  • run make fmt if you change code, and then use the pr-finisher skill before handing back for review

I also attempted a branch refresh for this PR in this run.

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

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 21.1 AIC · ⌖ 7.98 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 Aug 24, 2026

Copy link
Copy Markdown
Contributor Author

gh-aw-pr-sous-chef
@copilot PR Sous Chef triage: this PR still has unresolved review feedback.
...

Done in 72143d5 — the remaining gap was the maintainer-facing docs follow-up, so that is now the only change in this pass.

  • docs/src/content/docs/specs/checkout-behavior-specification.md: new normative §3.4 "Minimal safe_outputs PR Checkout" covering the root-only sparse default for implicit checkouts, the dropped fetch-depth/fetch: extras on explicit root checkouts, the git add --sparse staging requirement, the custom safe-output steps/actions/scripts opt-out, and that additional cross-repo checkouts are unaffected. Added the §5.1 fetch-step exception, T-CHK-016, the compliance-checklist row, and a change-log entry.
  • docs/src/content/docs/reference/checkout.md: user-facing "Checkout in the safe_outputs Job" section explaining what is narrowed, what is still honored, and when the full agent-identical checkout is kept.

The three earlier review threads were already answered in-thread (docs/comments in 1464b2f + 689656b, git add --sparse handling and nested-path regression coverage in 1464b2f).

Verification: go test ./pkg/workflow and the vitest suites pass (307 tests), and make recompile shows no lock drift. The agent, safe_outputs, CodeQL and copilot checks are green on the branch; the only failures in the local pre-PR gate are pre-existing and unrelated (largefunc lint in pkg/workflow/error_recovery.go, frontmatter_error.go, schedule_preprocessing.go, stop_after.go, plus a sandbox-only tsconfig/node-types JS lint error) — none of those files are touched by this PR.

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.

4 participants