Repository navigation
Make PR bundle history recovery explicit and validation offline - #68806
Conversation
Resolve trusted base tips with metadata only, deny transports during local bundle import and optional validation, and require per-handler opt-in for full history recovery. Surface actionable provisioning errors and cover shallow, partial-clone, metadata, credential, and schema behavior. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Observe temporary bundle refs through update-ref, preserve cleanup and tip assertions, and verify bundle application never fetches. Propagate offline execution options through the real-Git test adapter. Use a tagged switch for handler history-fetch test cases. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
✅ Design Decision Gate 🏗️ completed the design decision gate check. See the comment below for the result and any generated ADR draft. Commit pushed:
|
|
✅ Test Quality Sentinel completed test quality analysis. Test Quality SentinelOutcome: The agent completed and reported no action. A no-op output alone does not verify that all required work was completed or that publication was possible. Agent messages are omitted from this comment. The category uses structured run status, not interpretation of agent prose.
|
|
✅ PR Code Quality Reviewer completed the code quality review.
|
|
✅ Ponytail Reviewer completed successfully! Ponytail ReviewerOutcome: The agent completed and reported no action. A no-op output alone does not verify that all required work was completed or that publication was possible. Agent messages are omitted from this comment. The category uses structured run status, not interpretation of agent prose.
|
|
🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅
|
🏗️ Design Decision Gate — ADR RequiredThis PR makes significant changes to core business logic (121 new lines across 📄 Draft ADR committed:
📋 What to do next
Once an ADR is linked in the PR body, this gate will re-run and verify the implementation matches the decision. 🔍 Evidence used
❓ Why ADRs Matter
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 ReferenceAn ADR must contain these four sections to be considered complete:
All ADRs are stored in
|
Comment MemoryPeek at saved memory (pr-code-quality-reviewer)Note This comment is managed by comment memory.Expand the saved memory block to view or edit the persistent context for this thread.
|
There was a problem hiding this comment.
Request changes
The new allow-full-history-fetch recovery path is still tied to origin, so fork-backed PR updates can't actually recover when the missing prerequisite commits live only on the configured head repository.
The blocking theme
- Fork / cross-repo correctness:
push_to_pull_request_branchalready knows which remote and credentials are valid for the PR head, but the recovery helper unconditionally fetches fromorigin. That makes the new opt-in incomplete for one of the most failure-prone PR topologies.
The inline comment points at the exact spot that needs the remote/auth context threaded through.
🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 104.7 AIC · ⌖ 7.67 AIC · ⊞ 21.3K
Comment /review to run again
There was a problem hiding this comment.
Skills-Based Review 🧠
Applied /codebase-design and /diagnosing-bugs on this offline bundle-transport hardening PR. No blocking issues found — approving.
📋 Key Themes & Highlights
Verification performed
- Traced
ensureFullHistoryForBundle,importLocalBundle,offlineGitOptions, andresolveTrustedBaseTipend-to-end acrossgit_helpers.cjs,create_pull_request.cjs, andpush_to_pull_request_branch.cjs. - Confirmed the new
allow-full-history-fetchconfig is handler-scoped (not global), defaults tofalse, and is rejected by the JSON schema when passed as a string/expression (schema validation runs before Go config parsing, so a non-boolean value never silently falls through). - Ran
go test ./pkg/workflow/... -run TestAllowFullHistoryFetchandgo test ./pkg/parser/... -run TestMainWorkflowSchema_AllowFullHistoryFetch— all pass. - JS vitest suites could not be executed in this sandbox (npm registry blocked by self-signed cert, matching the PR body's noted dependency-restoration limitation); reviewed the new
bundle_transport.integration.test.cjsand updatedgit_helpers.test.cjs/push_to_pull_request_branch.test.cjsassertions by inspection instead — they correctly assert zero fetch calls, pack-file stability, and no credential leakage in thrown errors.
Positive highlights
- ✅ Clear separation of concerns:
offlineGitOptions()centralizes the transport-denial guard (GIT_ALLOW_PROTOCOL=""+GIT_NO_LAZY_FETCH=1+GIT_TERMINAL_PROMPT=0), used consistently across bundle inspection/import call sites. - ✅
resolveTrustedBaseTipvalidates the ref format before touching the network, requires an exact single-linels-remotematch, and swallows diagnostic output so stderr from a failed/unauthenticated remote never reachescore.warning(verified against the synthetic-credential integration test). - ✅ Error messages are fixed, actionable strings (pointing at
allow-full-history-fetch) rather than raw git stderr, matching the PR's stated goal of avoiding credential-bearing diagnostics. - ✅ Go/JS config field naming (
allow-full-history-fetch→AllowFullHistoryFetch→allow_full_history_fetch) is consistent end-to-end and mirrors the existingallow-workflowspattern. - ✅ Removing ~240 lines of nested retry/recovery branching from both PR handlers in favor of a single
importLocalBundlehelper is a solid simplification that should make this code much easier to reason about going forward.
Minor observations (non-blocking)
deepenOptions.baseRefis still documented in theensureFullHistoryForBundleJSDoc as "kept for existing callers" but is no longer read anywhere in the function body — worth removing from the signature/callers in a later cleanup pass once all call sites are confirmed migrated.- Could not independently execute the new JS test suites in this sandbox due to npm registry restrictions; relying on the PR's reported "592 passing tests" claim and static review of the test logic.
@copilot please address the review comments above.
🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet50 · 152.2 AIC · ⌖ 16.7 AIC · ⊞ 10.4K
Comment /matt to run again
There was a problem hiding this comment.
🔵 Needs a closer look
Security-sensitive Git provenance and transport changes need human sign-off while pinned JavaScript validation gates remain incomplete.
0 open findings
What changed in this PR
Updates gh-aw’s PR safe-output handlers to keep bundle validation offline and require explicit permission for history recovery, following the earlier base-tip fetch change and revert.
Changes:
- Resolve trusted base tips through metadata-only remote lookup.
- Import and inspect bundles offline; make prerequisite downloads opt-in per handler.
- Add configuration validation, documentation, and regression coverage.
| File | Description |
|---|---|
| pkg/workflow/safe_outputs_handler_registry_pull_requests.go | Serializes handler-specific recovery flags. |
| pkg/workflow/push_to_pull_request_branch.go | Parses the push handler’s recovery option. |
| pkg/workflow/create_pull_request.go | Defines the create handler’s recovery option. |
| pkg/workflow/compiler_safe_outputs_config_targets_test.go | Tests defaults, isolation, and serialization. |
| pkg/parser/schemas/main_workflow_schema.json | Adds literal-boolean recovery settings. |
| pkg/parser/schema_safe_outputs_target_test.go | Tests accepted values and invalid configuration. |
| docs/src/content/docs/reference/safe-outputs.md | Introduces the recovery option. |
| docs/src/content/docs/reference/safe-outputs-pull-requests.md | Explains offline validation and recovery risks. |
| actions/setup/js/types/handler-factory.d.ts | Types the runtime recovery flag. |
| actions/setup/js/push_to_pull_request_branch.test.cjs | Updates push-handler regression tests. |
| actions/setup/js/push_to_pull_request_branch.cjs | Uses metadata lookup and offline bundle validation. |
| actions/setup/js/git_helpers.test.cjs | Updates prerequisite and no-fetch tests. |
| actions/setup/js/git_helpers.cjs | Adds offline import and explicit history recovery. |
| actions/setup/js/create_pull_request.test.cjs | Updates create-handler recovery tests. |
| actions/setup/js/create_pull_request.cjs | Imports bundles locally with opt-in recovery. |
| actions/setup/js/create_pull_request_bundle_integration.test.cjs | Adapts integration checks to local import. |
| actions/setup/js/bundle_transport.integration.test.cjs | Adds real-Git transport and recovery coverage. |
🧠 Review effort: Max
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
Use the validated PR head remote for explicit prerequisite recovery while preserving target-origin metadata discovery and offline bundle validation. Cover fork-only objects, literal opt-in, credential restoration, and safe failures. Complete the ADR and document the credential boundary. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
In response to the ADR gate result: I reviewed and completed the generated ADR, including the change/revert history, credential boundaries, alternatives, and tradeoffs. The finalized proposal is linked in the PR description. |
|
In response to the Test Quality Sentinel result: this status notice requests no concrete code change, so no separate implementation change is needed. The fork-recovery fix has focused helper, handler, credential, and real-Git regression coverage; I did not treat |
|
In response to the code quality review result: accepted the associated fork-recovery finding. Both unshallow and fetch-by-SHA now use the validated PR head remote with scoped head credentials, while trusted base discovery remains target-origin metadata-only. |
|
In response to the Ponytail Reviewer result: no code change is needed for this status-only notice. The actionable fork-recovery and ADR findings were addressed separately, without treating the no-action result as evidence of completion. |
|
In response to the skills-based review: accepted the cleanup observation and removed the obsolete |
|
In response to the ADR requirement: completed ADR-68806 with concrete context, recovery authorization and credential isolation, real alternatives, and operational tradeoffs. The ADR is linked in the PR description and remains a proposal pending maintainer acceptance. |
|
In response to the saved review memory: addressed inline finding 4275548211 by using the validated PR head remote and scoped head credentials for explicit history recovery, with fork-only prerequisite and credential-restoration regressions. The managed memory block itself was left unchanged. |
|
@copilot address the following outstanding work in one pass:
Push the necessary fixes, reply to each listed review thread and resolve it when addressed. Ignore feedback already answered or resolved. Use the pr-finisher skill and stop when only human review or CI remains; do not trigger CI. Sous-chef head: d050619
|
…-git-downloads Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
| --- | ||
| "gh-aw": patch | ||
| --- | ||
|
|
||
| Make pull request bundle history recovery explicit and keep bundle validation offline unless full-history fetching is enabled for the applicable safe-output handler. |
There was a problem hiding this comment.
Changed the changeset to major and added breaking-change migration guidance. The opt-in authorizes potentially unbounded prerequisite recovery; local bundle import and validation remain offline. Commit: b61d266.
|
|
||
| ### Bundle prerequisites and history downloads | ||
|
|
||
| `create-pull-request` and `push-to-pull-request-branch` import bundles without automatic prerequisite downloads by default. A missing prerequisite fails with guidance to provision the required objects in the target checkout, or explicitly enable recovery: |
There was a problem hiding this comment.
Updated the workflow steps to describe offline git bundle unbundle, default failure/provisioning or handler-specific recovery opt-in, and the requirement that necessary bundle objects be available when the base advances. Commit: b61d266.
|
@copilot address the following outstanding work in one pass:
Push the necessary fixes, reply to each listed review thread and resolve it when addressed. Ignore feedback already answered or resolved. Use the pr-finisher skill and stop when only human review or CI remains; do not trigger CI. Sous-chef head: 42c5cb7
|
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
|
@copilot Fix the code for all comments in this review thread. When a review comment includes a suggested change, apply the suggestion exactly. Do not make changes beyond what is described in the linked review thread. |
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
The two findings linked from review |
|
@copilot merge main and recompile |
|
@copilot address the following outstanding work in one pass:
Push the necessary fixes, reply to each listed review thread and resolve it when addressed. Ignore feedback already answered or resolved. Use the pr-finisher skill and stop when only human review or CI remains; do not trigger CI. Sous-chef head: f8c36e8
|
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Fixed the transport-integrity test fixtures to match offline bundle import; the affected suites and 634 impacted JS tests now pass. Pinned gopls to v0.23.0, which installs with Go 1.26.9, addressing the setup failures. Commit: |
|
🎉 This pull request is included in a new release. Release: |


Summary
Replace the live-base fetch from #68717, reverted by #68795, without restoring unrestricted automatic history downloads in shallow monorepos.
git ls-remote --refs --exit-codeagainst the target checkout's origin. Validate the returned ref/SHA and pin the SHA; never fetch objects solely to establish this optional validation baseline.git bundle unbundle. Bundle import, prerequisite checks, optional ancestry/tree inspection, and the push handler's bundle diff/history checks deny Git transports withGIT_ALLOW_PROTOCOL=""plusGIT_NO_LAZY_FETCH=1. Protocol denial also protects Git versions that ignore lazy-fetch suppression.Configuration and compatibility
Both settings independently default to false, accept only literal booleans, and belong to the applicable handler—not the global
safe-outputsobject:Prefer provisioning required objects during authenticated checkout. If prerequisites are missing, the error explains that approach and how to enable recovery under the applicable handler.
Opting in permits unbounded downloads, including
--unshallowand fetch-by-SHA. Exact SHAs, commit-depth limits, and blob filters are not byte bounds. The opt-in never enables object fetching for optional baseline discovery.Shallow checkouts remain supported when the necessary objects are present. Partial clones can fail offline when required trees/blobs are missing, even if prerequisite commits exist. Conservative fallback can reject otherwise valid base merges rather than exclude unverified history. This is not a network-free handler: ordinary PR-head fetch/push and existing signed-push recovery remain outside this focused policy.
The JS handlers, TypeScript configuration, Go parsing/runtime serialization, workflow schema, reference documentation, and tests are updated together. ADR-68806 documents the decision, alternatives, credential separation, and compatibility tradeoffs; its status remains Proposed, pending maintainer acceptance.
Current branch and validation
Merged
mainthrough1707e20ece0fe899f193963905ec594bcc0700a1and pushed merge commit94b9d572d6af9756299bb1347558c3bb5763e404. No merge conflicts; all 344 workflows recompiled successfully.--testTimeout=20000. Coverage includes real shallow/partial repositories, offline import and optional-baseline inspection, missing prerequisites, metadata/authentication fallback, filtering-unsupported servers, fork-only recovery, literal opt-in, credential restoration, and protection checks.make agent-report-progress: regular Go lint, JavaScript lint, schema checks, and impacted Go tests passed. Impacted JS tests reported 801 passed and one timeout across 11 suites. JavaScript lint has non-blocking warnings.Remaining local gate limitations
The final progress gate is not fully green:
parseCreatePullRequestsConfigat 109 lines andparsePushToPullRequestBranchConfigat 164 lines, against a 60-line limit.The earlier pinned-dependency installation blocker is resolved. No production bandwidth measurements or bandwidth-bound claims are made. No workflow runs were manually triggered; this PR has not been merged and auto-merge has not been enabled.
Changeset
✨ PR Review Safe Output Test - Run 38644688115