Add agent compatibility matrix and validation#32396
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a versioned compatibility matrix that pins agentic CLI versions to gh-aw release ranges, plus a JSON Schema and a CI validation step. The matrix is documentation-only until the gh-aw-actions/setup action consumes it.
Changes:
- New
.github/aw/compat.jsonwith v1 catch-all + bounded rows for thecopilotagent. - New
.github/aw/compat.schema.json(draft-07) covering shape, types, and semver formats. - New inline
actions/github-scriptvalidation step incgo.ymlenforcing semantic rules (range ordering, non-overlap,openonly on catch-all, no unknown fields) on every PR touching the matrix files.
Show a summary per file
| File | Description |
|---|---|
.github/aw/compat.json |
Initial v1 matrix data (catch-all + bounded copilot rows). |
.github/aw/compat.schema.json |
JSON Schema describing the matrix shape and semver formats. |
.github/workflows/cgo.yml |
Adds compat.json/compat.schema.json to path filters and adds a new validation step mirroring the existing releases.json validator. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (1)
.github/aw/compat.schema.json:61
- The JSON schema permits
openon every row (including bounded rows), but the inline validator at lines 808–810 rejectsopenon any row whosemax-gh-awis not"*". This means a compat.json that passes the schema can still fail the inline validator. Either tighten the schema (e.g., split into two row variants viaoneOf/if-thenso thatopenis only permitted whenmax-gh-aw == "*"), or relax the validator, so the two stay in sync. Otherwise downstream consumers that only run the schema (e.g., the setup action, IDE tooling) will accept files that CI later rejects.
"row": {
"type": "object",
"required": ["min-gh-aw", "max-gh-aw", "min-agent", "max-agent"],
"additionalProperties": false,
"properties": {
"min-gh-aw": { "$ref": "#/definitions/semver" },
"max-gh-aw": { "$ref": "#/definitions/ghAwBound" },
"min-agent": { "$ref": "#/definitions/semver" },
"max-agent": { "$ref": "#/definitions/semver" },
"open": {
"type": "boolean",
"description": "When false, the setup action stops bumping max-agent for this row (rollback / quarantine state)."
}
}
}
- Files reviewed: 3/3 changed files
- Comments generated: 4
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
CI status (2026-05-15 14:08Z): The new The CGO workflow itself shows red because of an unrelated Lint Gate failure on |
This comment has been minimized.
This comment has been minimized.
Add .github/aw/{compat.json,compat.schema.json} to declare which agent
CLI versions are validated against which gh-aw release ranges. The
gh-aw-actions/setup action will eventually consume this matrix to
install a known-good agent version per gh-aw release; until that lands,
the matrix is documentation.
Files mirror the existing .github/aw/releases.json convention. Sync to
github/gh-aw-actions runs as part of the release process so the runtime
fetch URL (raw.githubusercontent.com/github/gh-aw-actions/main/.github/aw/compat.json)
stays the source of truth for live runs.
Validation step in cgo.yml checks JSON shape, semver formats, and the
cross-row invariants the schema cannot express (min<=max, non-overlapping
gh-aw ranges, 'open' only on the catch-all row), in the same inline
actions/github-script style as the existing releases.json validator.
…ards Address validation gaps in the inline compat.json validator: - compat.schema.json: add an if/then so 'open' is only permitted when 'max-gh-aw' == "*". Schema-only consumers (IDE tooling, external validators) now reject bounded rows that include 'open' instead of passing them and leaving the rejection to CI. - cgo.yml validator: gate the bounded-row 'open' check on 'max-gh-aw' actually being present in the row, so a row missing the required 'max-gh-aw' field reports only the genuine missing-field error instead of also raising a misleading 'open only on catch-all' error. - cgo.yml validator: implement full semver 2.0.0 ordering (prerelease identifiers handled per spec) so a row like 'min: 1.0.0, max: 1.0.0-alpha' is correctly flagged as min>max. - cgo.yml validator: introduce a cmpGhAw helper that treats '*' as +infinity directly, removing the magic 999999.0.0 sentinel from the overlap pass. - cgo.yml validator: skip non-object rows in the overlap pass so a null row entry surfaces as the existing 'must be an object' error instead of throwing on property access.
abdd8ad to
4b1130d
Compare
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Skills-Based Review 🧠
Applied /grill-with-docs — this PR introduces new domain concepts (agent-compat-v1, open, cache-ttl-days) with new terminology, a JSON schema, and inline validation logic that all need to agree.
Key Themes
-
openfield semantics are ambiguous — the field is described as "when false, stop bumping", but the implicit default when the field is omitted is never documented in the schema or the validator. A"default": truein the schema would make this self-describing. -
$idpoints to the consumer, not the source —compat.schema.jsonusesgh-aw-actionsas the schema's canonical$idwhile living ingh-aw. Schema tooling that resolves$idwill get a 404 until the companion PR merges. -
Two sources of truth for allowed agent names —
allowedAgentKeysin the validator duplicates theagent-compat-v1.propertieslist in the schema. A linking comment at minimum, or reading the schema's property names at runtime, would prevent them drifting when a new engine is added. -
cmp()is not null-safe — ifparseSemverever returnsnull(guarded in practice, but not defensively), the function throws aTypeErrorinstead of producing a clean validation error. -
Log message implies
ajvschema validation ran when it didn't — the success message on line 866 says the schema is "the schema contract", but only hand-rolled checks execute. The existingreleases.jsonstep has the same pattern; small wording fix makes it accurate. -
Inclusive overlap bounds are undocumented — the
<=comparison means two rows sharing a boundary version (e.g., both claim0.72.0) are flagged as overlapping. This is correct and intentional, but a one-line comment saves future range authors a head-scratch.
Positive Highlights
- ✅ Thorough validator test coverage — the PR description lists six failure cases exercised locally (min>max, open on bounded row, overlapping rows, unknown property, unknown agent, missing required field). That's a solid test surface for an inline script.
- ✅ Clean split-lifecycle shape — the catch-all / bounded-row design is well-explained in the PR and maps directly to the data. The
0.71.99boundary is unambiguous. - ✅ Mirrors the existing
releases.jsonpattern — reusing the same CI job, the samegithub-scriptaction pin, and the same file layout keeps thevalidate-yamljob coherent and easy to navigate. - ✅
additionalProperties: falsethroughout the schema — tight schema prevents silent property typos, which is the right default for a pinned-version matrix.
Verdict
No blocking issues — the data, schema, and validator are functionally correct. The comments above are mostly about documentation precision and defensive coding. Happy to see this land as-is with the inline comments addressed in a follow-up if preferred.
🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · ● 8.3M
- compat.schema.json: declare 'open' default as true so consumers and future maintainers do not have to infer it from absence; expand the description to spell out the rollback/quarantine semantic. - compat.schema.json: point $id at the gh-aw source-of-truth path instead of the gh-aw-actions consumer path, so JSON Schema tooling that resolves $id for cross-schema references uses the canonical source URL. - cgo.yml validator: throw an explicit error in cmp() when called with a non-semver string; in practice the surrounding semverRe.test() guards prevent reaching this, but the explicit throw makes the helper self-contained. - cgo.yml validator: comment that the in-validator allowedAgentKeys set must stay in sync with agent-compat-v1.properties in the schema, surfacing the cross-file coupling for future engine additions. - cgo.yml validator: drop the schema-contract phrasing from the success log so the message no longer implies that an ajv-style schema validation step ran (the validator is hand-rolled inline, matching the existing releases.json pattern). - cgo.yml validator: comment that the gh-aw range overlap check is closed/inclusive on both ends, so two rows sharing a boundary version count as overlapping.
|
✅ smoke-ci: safeoutputs CLI comment + comment-memory run (25924408935)
|
|
Please resolve the open review threads and post a brief blocker summary if anything remains.
|
|
|
Add
.github/aw/compat.json— the matrix that pins agentic CLI versions to gh-aw release ranges. Thegh-aw-actions/setupaction will eventually consume this matrix to install a known-good agent version per gh-aw release; until that lands, the matrix is documentation.This file lives in gh-aw because gh-aw is the source of truth — the existing
sync-actionsworkflow ongithub/gh-aw-actionsmirrors files from gh-aw as part of the release process. A companion PR on gh-aw-actions extendssync-actionsto mirror the new compat files alongside the existing setup-action sources, so the runtime fetch URL (raw.githubusercontent.com/github/gh-aw-actions/main/.github/aw/compat.json) keeps working.Files
.github/aw/compat.json.github/aw/compat.schema.json.github/workflows/cgo.ymlValidate compat.json structure and version formatsstep in thevalidate-yamljobThe shape of the changes mirrors the existing
.github/aw/releases.json+.github/aw/releases.schema.json+ inlineactions/github-scriptvalidator already incgo.yml. No new dependencies, no new files outside.github/aw/.Initial v1 contents
Split-lifecycle shape with one catch-all and one bounded row:
0.72.0..*1.0.211.0.48true0.0.1..0.71.990.0.01.0.21How the catch-all range was determined
A 12-version sweep ran the canary's working scenarios against each of the following copilot CLI versions on
gh-aw v0.72.1:1.0.21, 1.0.22, 1.0.23, 1.0.25, 1.0.27, 1.0.30, 1.0.33, 1.0.36, 1.0.40, 1.0.43, 1.0.46, 1.0.48Six canary scenarios were used as the bump-bar (the four
safe-outputs.create-pull-requestscenarios are currently broken for unrelated reasons and were excluded):code-search— github MCP read path (search files / content)create-issue—safe-outputs.create-issuewrite pathdetection-not-skipped— explicit regression test for the v1.0.22 silent-success fingerprintlist-prs— github MCP read path (list PRs and issues)strict-mode— strict-mode end to endtool-connectivity— MCP tool surface non-emptyAll twelve versions passed all six scenarios on the agent / detection / safe_outputs jobs. (Some runs showed
cancelledon theconclusionjob due to a globalgh-aw-conclusion-<scenario>concurrency group stomping across the sweep branches; the cancellation does not reflect a CLI failure.)Bounded row
max-agent: 1.0.21forgh-aw 0.0.1 .. 0.71.99is the last copilot CLI version known to work with pre-0.72gh-aw releases before thev1.0.22detection-skip incident (#25550). That specific failure mode no longer reproduces against currentgh-awbecause several MCP servers (safeoutputs,mcpscripts) moved out of the gateway and into agent-container CLI tools, narrowing the surface that the v1.0.22 bug could affect.Validation
The new step in
cgo.ymlruns on every PR that touches.github/aw/compat.jsonor.github/aw/compat.schema.json. Schema covers shape & types; the inline JS covers:min-agent <= max-agentper rowmin-gh-aw <= max-gh-awper row (ormax-gh-aw == "*")openfield permitted only on the catch-all (max-gh-aw == "*") row; bounded rows are closed-by-constructionValidator was exercised locally against the happy path and against six failure cases (min>max, open on bounded row, overlapping rows, unknown row property, unknown agent, missing required field) — each case was caught with a clear error message.
What this does not do
gh-aw-actions/setupaction — until that ships, the matrix is documentation. Production gh-aw still installs whatever default it ships.max-agentmoves through human PRs as part of the weekly release.These are tracked as follow-ups.