Fix DefaultCopilotVersion toolcache bypass caused by compat.json drift#48593
Conversation
… range fallback, emit GH_AW_COMPILED_VERSION in job envs Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Fixes Copilot CLI toolcache bypasses caused by compatibility-window drift and missing compiler-version context.
Changes:
- Updates the supported Copilot CLI range.
- Enables compatibility-range matching for cached installations.
- Emits compiler versions and adds drift-prevention tests.
Show a summary per file
| File | Description |
|---|---|
.github/aw/compat.json |
Extends the Copilot compatibility window. |
actions/setup/sh/install_copilot_cli.sh |
Adds explicit-version range fallback. |
pkg/constants/version_constants_test.go |
Guards against version drift. |
pkg/workflow/compiler_main_job_helpers.go |
Exposes compiler version to agent jobs. |
pkg/workflow/threat_detection_job.go |
Exposes compiler version to detection jobs. |
Review details
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 5/5 changed files
- Comments generated: 3
- Review effort level: Medium
|
✅ Design Decision Gate 🏗️ completed the design decision gate check. |
|
✅ Test Quality Sentinel completed test quality analysis. |
|
🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅ |
|
✅ PR Code Quality Reviewer completed the code quality review. |
Test Quality Sentinel Report - Score: 100/100 Excellent - 2 design tests, 0 violations. Both tests are behavioral_contract/high_value/design_test. Verdict: PASSED (0% implementation tests, threshold 30%)
|
There was a problem hiding this comment.
Review: Fix DefaultCopilotVersion toolcache bypass
The fix correctly addresses the root cause (stale compat.json max-agent + exact-match-only toolcache lookup). Overall approach is sound. Three pre-existing Copilot review comments cover the notable non-blocking issues:
- Explicit version becomes a soft hint — any workflow pinning
engine.version: Xwill now silently accept a compat-range match whenGH_AW_COMPILED_VERSIONis present. - TTL exemption still applies to explicit requests — a stale toolcache entry won't be expired when
requested_version != latest. openbool default in test — Go JSON unmarshaling maps an omittedopenfield tofalse; the test would miss any future open row relying on the schema default.
No blocking issues found. The CI gate test (TestDefaultCopilotVersionWithinCompatWindow) is a good addition to prevent drift from recurring.
🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 33.8 AIC · ⌖ 5.68 AIC · ⊞ 5K
Draft ADR capturing the decision to run compat-matrix resolution unconditionally (even for explicit version requests) so the runner toolcache can satisfy Copilot CLI installs without a network download.
🏗️ Design Decision Gate — ADR RequiredThis PR makes significant changes to core business logic (125 new lines in 📄 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. ❓ 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
|
There was a problem hiding this comment.
Skills-Based Review 🧠
Applied /diagnosing-bugs and /tdd. The fix correctly addresses all four root causes identified in the PR description and adds a solid CI gate. A few follow-up items worth addressing before merge.
📋 Key Themes & Highlights
Key Themes
openbool decode (existing comment #3665567402):json.Unmarshalmaps omittedopen→false; the test skips rows whereopen == false, so a schema-valid row without an explicitopen: trueis silently ignored — the CI gate would pass even if the version drifted outside that row's range- Soft-hint concern (existing comment #3665567324): the fallthrough from exact-match to range check means any workflow pinned to a specific explicit version can silently install a different (compatible) version; the behaviour change is intentional but deserves an integration test
- TTL exemption gap (existing comment #3665567363): the TTL bypass for explicit versions is not updated to account for the new range-match path
- Wildcard
max-agent(new comment):semverCmpwill panic-via-Fatal ifmax-agentis ever"*"; add a guard IsRelease()nil check (new comment):if env == nilinbuildMainJobEnvis dead code; worth a comment to explain the dev/release asymmetry
Positive Highlights
- ✅ All four root causes are identified and addressed in a single coherent change
- ✅
TestDefaultCopilotVersionWithinCompatWindowis an excellent CI gate — exactly the right kind of regression prevention - ✅
parseSemver/semverCmpare clean, self-contained, and easy to test in isolation - ✅ Shell changes preserve backward-compatibility: when no compat window is available, exact-match still applies
🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 44.9 AIC · ⌖ 4.93 AIC · ⊞ 6.7K
Comment /matt to run again
There was a problem hiding this comment.
Verdict: REQUEST_CHANGES
The fix correctly addresses the reported toolcache bypass, but the new explicit-version compat-range fallthrough introduces a regression that silently disables cache freshness checks.
💡 Themes and highlights
Blocking:
install_copilot_cli.sh: the fallthrough that lets an explicit version match a compat-range candidate bypasses the TTL-expiry check entirely, because that check is guarded byrequested_version = "latest". This means an explicit-version install can now silently reuse an arbitrarily old cached binary within the compat window with no freshness check at all — the opposite of the intended fix's rigor.
Non-blocking / lower priority:
version_constants_test.go:parseSemverrejects any prerelease-suffixed version (e.g.1.0.75-beta.1) despite the compat.json schema explicitly permitting one, which would turn a schema-valid config into a confusing test failure rather than a real compat violation.- A prior reviewer already flagged the
Open boolJSON-decode default mismatch (schema saysopendefaults totruewhen omitted, but the Go struct defaults tofalse) — worth fixing alongside the above. - The
compat.jsonbump andGH_AW_COMPILED_VERSIONenv-injection changes themselves look correct and are consistent betweencompiler_main_job_helpers.goandthreat_detection_job.go.
Recommend extending the TTL check to also apply on the explicit-version + range-match path before merging.
🔎 Code quality review by PR Code Quality Reviewer · sonnet50 · 73.8 AIC · ⌖ 4.4 AIC · ⊞ 7.4K
Comment /review to run again
Comments that could not be inline-anchored
actions/setup/sh/install_copilot_cli.sh:431
This fallthrough lets an explicit-version request match a stale cached binary within the compat range, but the TTL-expiry check below only fires when requested_version = "latest" — so explicit-version installs now silently accept an expired cache entry with zero freshness check.
pkg/constants/version_constants_test.go:179
parseSemver hard-fails on any prerelease-suffixed version (e.g. 1.0.75-beta.1), even though compat.schema.json's semver definition explicitly permits a -prerelease suffix.
|
@copilot run pr-finisher skill |
…comment, default-pin-only range fallback Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
@copilot review changes against the spec. |
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Reviewed against the spec and fixed the remaining gaps in |
| "max-gh-aw": "*", | ||
| "min-agent": "1.0.21", | ||
| "max-agent": "1.0.56", | ||
| "max-agent": "1.0.75", |
There was a problem hiding this comment.
@copilot since it's open max-agent should be *
DefaultCopilotVersion(1.0.75) exceeded thecompat.jsonmax-agent(1.0.56), which causedinstall_copilot_cli.shto skip compat resolution entirely when passed an explicit version—meaning the1.0.56runner toolcache entry was always rejected via exact-match, forcing a network download on every agentic job.Root causes
compat.jsonmax-agentwas stale relative toDefaultCopilotVersion$VERSIONwas set, leavingCOMPAT_MATCHED_MIN/MAX_AGENTemptyfind_cached_copilot_binused exact-match-only when a version was explicit (continuepast the range check), so a compatible toolcache entry was always rejectedGH_AW_COMPILED_VERSIONwas never emitted in agent/detection job envs, so the install script had nocompiled_versionto resolve a compat window even if it wanted toChanges
.github/aw/compat.jsonmax-agent:1.0.56→1.0.75actions/setup/sh/install_copilot_cli.shMAJOR.MINOR.PATCH(with or withoutv) inGH_AW_COMPILED_VERSIONvalidation —c.versionin the compiler is"0.83.1"not"v0.83.1"$VERSIONis explicit, populatingCOMPAT_MATCHED_MIN/MAX_AGENTfor range-based toolcache matchingfind_cached_copilot_bin: when exact match fails but a compat range is available, fall through to the range check instead of skipping — lets cached1.0.56satisfy an explicit request for1.0.75when both are within the compat windowpkg/workflow/compiler_main_job_helpers.go/threat_detection_job.goGH_AW_COMPILED_VERSION: <version>in job-level env for released builds, enabling the install script to perform compat resolution and populate the range for toolcache matchingpkg/constants/version_constants_test.goTestDefaultCopilotVersionWithinCompatWindow: reads.github/aw/compat.json, finds the open compat row, and assertsmin-agent ≤ DefaultCopilotVersion ≤ max-agent— CI gate to prevent this class of drift from recurring