Skip to content

Upgrade gh-aw to v0.56.0 and use protected-files guards#599

Merged
strawgate merged 2 commits intomainfrom
bill/upgrade-gh-aw-v0-56-0-protected-files
Mar 8, 2026
Merged

Upgrade gh-aw to v0.56.0 and use protected-files guards#599
strawgate merged 2 commits intomainfrom
bill/upgrade-gh-aw-v0-56-0-protected-files

Conversation

@strawgate
Copy link
Collaborator

@strawgate strawgate commented Mar 8, 2026

Summary

  • upgrade the gh-aw compiler to v0.56.0 in Makefile
  • add native safe-output protected-files guards for .github/** in both PR write paths:
    • .github/workflows/gh-aw-fragments/safe-output-create-pr.md
    • .github/workflows/gh-aw-fragments/safe-output-push-to-pr.md
  • remove redundant prompt-only .github/workflows prohibition text and align workflow-edit-guardrails with runtime-enforced protected paths
  • regenerate compiled lock workflows for the new compiler/runtime output (including updated github/gh-aw/actions/setup pins)
  • stabilize workflow linting by removing agentics-maintenance.yml from make lint-workflows target files

Test plan

  • git diff review of updated fragments, generated lock workflows, and Makefile
  • make compile (attempted earlier, but go install github.com/github/gh-aw/cmd/gh-aw@v0.56.0 hung in this environment)
  • make lint-workflows

The body of this PR is automatically managed by the Trigger Update PR Body workflow.

Move workflow path protection to safe-outputs `protected-files` for create/push flows and simplify prompt guardrails to rely on runtime enforcement.

Made-with: Cursor
@coderabbitai
Copy link

coderabbitai bot commented Mar 8, 2026

📝 Walkthrough

Walkthrough

This PR updates GitHub Actions workflow fragments to enforce protection on .github/** paths via safe-outputs. It adds protected-files patterns to three fragment files (safe-output-create-pr.md, safe-output-push-to-pr.md, and workflow-edit-guardrails.md), replacing previous prohibition language with guidance that runtime blocking is enforced. The Makefile updates the GH_AW_VERSION from v0.53.6 to v0.56.0.

Possibly related PRs

Suggested labels

big_boom

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bill/upgrade-gh-aw-v0-56-0-protected-files
  • 🛠️ Update Documentation: Commit on current branch
  • 🛠️ Update Documentation: Create PR

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the medium_boom Medium PR blast radius; likely benefits from human review label Mar 8, 2026
github-actions[bot]

This comment was marked as resolved.

Commit compiled lockfile updates for the compiler bump, keep agentics-maintenance dispatch defaults lint-safe, and exclude generated maintenance workflow from actionlint file selection.

Made-with: Cursor
find .github/workflows -maxdepth 1 \( \
-name "trigger-*.yml" -o -name "trigger-*.yaml" -o \
-name "agentics-maintenance.yml" -o -name "ci.yml" -o \
-name "ci.yml" -o \
Copy link
Contributor

Choose a reason for hiding this comment

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

[MEDIUM] Workflow lint coverage regressed for agentics-maintenance.yml

This change removes agentics-maintenance.yml from make lint-workflows, but CI still relies on that target (.github/workflows/ci.yml, Validate workflows). As a result, syntax/expression problems in this workflow are no longer caught pre-merge and will only surface at runtime.

Please keep this workflow in the lint set (or add an equivalent validation path) so lint-workflows still protects it.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/agent-efficiency.lock.yml (1)

83-93: ⚠️ Potential issue | 🟠 Major

Fix GH_AW_INFO_AGENT_VERSION and Copilot CLI to use pinned versions in source workflows.

All ~80 compiled workflows reference GH_AW_INFO_AGENT_VERSION: "latest" and install_copilot_cli.sh latest, making failure analysis across runs non-deterministic. When CLI behavior or output changes, you lose the ability to bisect regressions by execution date.

Since .lock.yml files are generated by gh aw compile from .md source files, the fix must be in the source workflow(s) (not in the lockfiles directly). Either pin both GH_AW_INFO_AGENT_VERSION and the CLI installer to a concrete version, or resolve latest once at compile time and export the resolved version.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/agent-efficiency.lock.yml around lines 83 - 93, The
workflow lockfile shows GH_AW_INFO_AGENT_VERSION set to "latest" and calls to
install_copilot_cli.sh using "latest", which makes runs non-deterministic;
update the source workflow(s) (the .md files that gh aw compile uses) to replace
GH_AW_INFO_AGENT_VERSION: "latest" and any install_copilot_cli.sh latest
invocations with a concrete pinned version (or add logic to resolve and export
the resolved version at compile time) so the compiled .lock.yml contains
deterministic pinned values; ensure you modify the variables in the source
workflow(s) that define GH_AW_INFO_AGENT_VERSION and the installer invocation
rather than editing the generated .lock.yml directly.
🧹 Nitpick comments (12)
.github/workflows/gh-aw-pr-actions-fixer.lock.yml (1)

589-589: Note: Copilot CLI now uses "latest" instead of pinned version.

This reduces build reproducibility. If a future CLI release introduces breaking changes, workflows will fail without a corresponding code change. This appears intentional (matching GH_AW_INFO_AGENT_VERSION: "latest" on line 126), but worth confirming this is the desired behavior.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gh-aw-pr-actions-fixer.lock.yml at line 589, The workflow
currently calls install_copilot_cli.sh with the unpinned "latest" (the run step
invoking /opt/gh-aw/actions/install_copilot_cli.sh latest) and
GH_AW_INFO_AGENT_VERSION is also set to "latest"; to fix, decide whether you
want reproducible builds and then either pin both places to a specific Copilot
CLI version (replace "latest" with the chosen version string) or add an explicit
comment/justification and keep them as "latest"; update the run invocation and
GH_AW_INFO_AGENT_VERSION usage to match the chosen approach so both are
consistent.
.github/workflows/gh-aw-scheduled-audit.lock.yml (1)

131-131: Using "latest" for agent/CLI versions reduces reproducibility.

Both GH_AW_INFO_AGENT_VERSION (line 131) and the Copilot CLI install (line 620) now specify "latest" instead of pinned versions. Future runs may behave differently without any lockfile change.

If this is intentional (always-current tooling), no action needed. If reproducibility matters, consider pinning in the source .md.

Also applies to: 620-620

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gh-aw-scheduled-audit.lock.yml at line 131, Replace the
non-reproducible "latest" pins with explicit version strings: update the
GH_AW_INFO_AGENT_VERSION environment variable to a specific release (e.g.,
"vX.Y.Z") and change the Copilot CLI install step to install a fixed Copilot CLI
version instead of "latest"; locate the GH_AW_INFO_AGENT_VERSION definition and
the Copilot CLI install step in the workflow and substitute concrete version
numbers (or reference a variable that is set from a source-controlled .md or
lockfile) so CI runs are deterministic.
.github/workflows/gh-aw-performance-profiler.lock.yml (1)

733-733: Using latest for Copilot CLI installation reduces reproducibility.

The shift from a pinned version to latest means workflow behavior may change without lockfile updates. This is acceptable if the team prefers staying current automatically, but be aware that debugging regressions could be harder. If this is a concern, the change would need to be reverted in the source .md file.

Based on learnings: .lock.yml files are auto-generated by gh aw compile from .md source files — do not edit directly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gh-aw-performance-profiler.lock.yml at line 733, The
workflow currently uses an unpinned installer invocation
"/opt/gh-aw/actions/install_copilot_cli.sh latest" which lowers reproducibility;
revert this change in the source .md that generates the lockfile by pinning the
Copilot CLI version (replace "latest" with the desired semver or specific tag)
and then regenerate the lockfile with "gh aw compile" so the
.github/workflows/gh-aw-performance-profiler.lock.yml reflects the pinned
installer; do not edit the .lock.yml directly.
.github/workflows/gh-aw-mention-in-issue-by-id.lock.yml (1)

139-139: Using "latest" for Copilot CLI version.

Both GH_AW_INFO_AGENT_VERSION and the Copilot CLI install script now use "latest". This reduces build reproducibility but may be intentional for staying current. Since this is generated output, any adjustment would need to happen in the source .md files or the compiler defaults.

Also applies to: 597-597

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gh-aw-mention-in-issue-by-id.lock.yml at line 139, The
workflow currently pins GH_AW_INFO_AGENT_VERSION to the string "latest" and the
Copilot CLI install step also uses "latest", which hurts reproducibility; change
GH_AW_INFO_AGENT_VERSION from "latest" to a specific version tag or make it read
from an environment/inputs variable with a documented default, and update the
Copilot CLI install script to consume that same version variable (instead of
hardcoded "latest") so both the GH_AW_INFO_AGENT_VERSION and the Copilot install
reference a pinned/parameterized version (look for GH_AW_INFO_AGENT_VERSION and
the Copilot CLI install command to modify).
.github/workflows/gh-aw-text-auditor.lock.yml (1)

812-812: Copilot CLI install changed from pinned version to latest.

Same reproducibility concern as the agent version. Using latest means workflow behavior could change without any code changes, complicating debugging. This should be addressed in the source .md file if pinning is preferred.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gh-aw-text-auditor.lock.yml at line 812, The workflow
currently calls "/opt/gh-aw/actions/install_copilot_cli.sh latest", which uses
the floating "latest" tag and harms reproducibility; update that invocation to a
pinned version string (e.g., replace "latest" with the tested release tag you
want to lock to) or, if intentionally using "latest", add a clear note in the
corresponding source documentation file explaining the choice and the
recommended pinned alternative for reproducible runs.
.github/workflows/gh-aw-mention-in-pr-by-id.lock.yml (1)

142-150: Capture the resolved Copilot CLI version instead of the literal latest.

Line 149 records "latest" in the run metadata, and Line 707 installs "latest" at runtime. That drops the exact CLI build from the workflow artifacts, which makes regressions much harder to reproduce or bisect after an upstream release. Please resolve and persist the installed version from the source workflow/fragment path rather than emitting latest into the generated lockfile.

Based on learnings, .lock.yml files here are generated from source workflow content, so this should be fixed in the source .md/fragment or compiler path rather than editing the lockfile directly.

Also applies to: 706-707

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gh-aw-mention-in-pr-by-id.lock.yml around lines 142 - 150,
The GH_AW_INFO_AGENT_VERSION env var in the generate_aw_info step currently
hardcodes "latest"; change the source workflow/fragment or the compiler that
produces this lockfile so it resolves the Copilot CLI version at build time (the
exact installed tag/semver from the source fragment) and writes that concrete
version into GH_AW_INFO_AGENT_VERSION instead of "latest"; ensure the installer
step that installs Copilot CLI uses and persists the same resolved version so
the generated .lock.yml contains the reproducible CLI build rather than the
literal "latest".
.github/workflows/gh-aw-mention-in-pr-no-sandbox.lock.yml (1)

148-148: Pin the Copilot CLI instead of floating latest.

Line 767 switches the install to latest, and Line 148 then records only latest in the metadata. That makes runs drift over time and removes the exact version you need when debugging a behavior or log-format regression from the CLI. Please pin the CLI in the source workflow/fragment and emit the resolved version in GH_AW_INFO_AGENT_VERSION. Based on learnings, .github/workflows/*.lock.yml files are generated from corresponding .md source files via gh aw compile, so this change should be made in the source file rather than the lockfile.

Also applies to: 767-767

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gh-aw-mention-in-pr-no-sandbox.lock.yml at line 148,
Replace the floating "latest" pin for the Copilot CLI with a fixed, explicit
version and emit that resolved version into the GH_AW_INFO_AGENT_VERSION
variable instead of the string "latest"; update the source workflow/fragment
(the .md that generates the .github/workflows/*.lock.yml via gh aw compile) so
the installer step uses the exact Copilot CLI version and the metadata key
GH_AW_INFO_AGENT_VERSION records that resolved version, ensuring the lockfile
will be regenerated with the pinned value rather than relying on runtime
resolution.
.github/workflows/gh-aw-internal-gemini-cli-web-search.lock.yml (1)

612-612: Pin the canonical Gemini CLI install.

@google/gemini-cli@latest makes identical workflow revisions execute different binaries over time. Re-pin it in the source workflow/fragment so this file and gh-aw-deep-research.lock.yml recompile to the same known version.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gh-aw-internal-gemini-cli-web-search.lock.yml at line 612,
Replace the floating install "run: npm install -g `@google/gemini-cli`@latest"
with a pinned canonical version (e.g.
"@google/gemini-cli@<exact-version-or-sha>") so the workflow reproducibly
installs the same binary; ensure the chosen exact version matches the one used
in gh-aw-deep-research.lock.yml to keep both lock files compiling to the same
known CLI.
.github/workflows/gh-aw-deep-research.lock.yml (1)

617-617: Pin @google/gemini-cli to a fixed version.

npm install -g @google/gemini-cli@latest makes this compatibility copy resolve a different CLI over time. Re-pin it in the source workflow/fragment and recompile so the deprecated alias and canonical workflow keep matching.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gh-aw-deep-research.lock.yml at line 617, Replace the
floating tag in the npm install command so the workflow installs a fixed release
of the Gemini CLI instead of `@latest`: change the string
'@google/gemini-cli@latest' used in the run step (the `npm install -g` command)
to a specific version (e.g. '@google/gemini-cli@X.Y.Z'), then
recompile/regenerate the workflow fragment so the deprecated alias and canonical
workflow remain in sync.
.github/workflows/gh-aw-duplicate-issue-detector.lock.yml (1)

114-114: Verify the move to a floating Copilot CLI version is intentional.

This workflow now both installs latest and records GH_AW_INFO_AGENT_VERSION: "latest", which gives up deterministic runs and the exact CLI version in run metadata. gh-aw defaults engine version to latest, but also documents pinning when you want reproducible runs or to avoid breakage from a new CLI release. If this repo still wants deterministic workflow behavior, keep engine.version pinned in the source workflow/frontmatter. (github.github.com) Based on learnings, .lock.yml files under .github/workflows/ are generated from the corresponding source .md files, so any fix should land in the source file rather than here.

Also applies to: 592-592

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gh-aw-duplicate-issue-detector.lock.yml at line 114,
Verify whether using a floating Copilot CLI version is intentional; if you need
deterministic workflows, replace GH_AW_INFO_AGENT_VERSION: "latest" with a
pinned version string (matching engine.version in the source
workflow/frontmatter) and update the source .md that generates this .lock.yml
(not the generated .github/workflows/*.lock.yml) so engine.version is pinned in
the source; ensure the pinned version value you choose matches the installed CLI
and update any engine.version references accordingly.
.github/workflows/gh-aw-autonomy-atomicity-analyzer.lock.yml (1)

121-121: Pin the GitHub Copilot CLI version using engine.version in the source .md file.

The .lock.yml file is auto-generated from the source .md file by gh aw compile, so changes must be made to the source file, not this lockfile. To pin the Copilot CLI version instead of tracking latest, set engine.version in the workflow frontmatter (e.g., engine.id: copilot and engine.version: "0.0.422"). This prevents runtime behavior drift and makes failures easier to reproduce.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gh-aw-autonomy-atomicity-analyzer.lock.yml at line 121,
This lockfile line shows GH_AW_INFO_AGENT_VERSION set to "latest" but the
correct fix is to update the source workflow .md frontmatter (not the generated
.lock.yml) to pin the Copilot CLI via engine.version; edit the source .md
workflow frontmatter to include engine.id: copilot and engine.version: "0.0.422"
(or your desired exact version) and then re-run gh aw compile to regenerate the
.lock.yml so the generated GH_AW_INFO_AGENT_VERSION is pinned instead of
"latest".
.github/workflows/gh-aw-bug-exterminator.lock.yml (1)

582-583: Consider re-pinning the Copilot CLI in the source workflow.

Line 583 switches this PR-producing workflow to install_copilot_cli.sh latest, so behavior can drift across runs as new Copilot CLI releases ship. gh-aw uses latest by default, but it also supports explicit version pinning when you want reproducible runs or to avoid new-release breakage. If deterministic PR generation matters here, keep the Copilot CLI version pinned in the corresponding source .md and recompile. (github.github.com)

Based on learnings: files under .github/workflows/*.lock.yml are auto-generated by gh aw compile from .md sources, so edits should be made in the source Markdown.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gh-aw-bug-exterminator.lock.yml around lines 582 - 583,
The workflow currently uses an unpinned call "run:
/opt/gh-aw/actions/install_copilot_cli.sh latest" which makes PR generation
non-deterministic; to fix, update the source workflow Markdown (not this
generated .lock.yml) to replace "latest" with an explicit Copilot CLI version
string (e.g., a specific tag) and then recompile with gh aw compile so the
generated .github/workflows/*.lock.yml will reflect the pinned version; look for
the install step in the source .md that emits install_copilot_cli.sh and change
the argument from "latest" to the chosen pinned version.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/gh-aw-code-duplication-fixer.lock.yml:
- Line 1721: Update the source workflow/fragment (not the generated .lock.yml)
that produces GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG so the issue-selection step (the
job/step that currently picks any open refactor issue—look for names like
pick_candidate_issue or select_candidate_issue) filters out or early-skips
candidates whose changed files match the protected_path_prefixes (".github/",
".agents/") before any agent work starts; ensure the same
protected_path_prefixes value used in GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG is
applied to the candidate filtering logic so protected-path duplication issues
are rejected before edits begin.

In @.github/workflows/gh-aw-issue-triage.lock.yml:
- Line 118: Replace the ambiguous "latest" with fixed version strings to ensure
reproducible runs: change the GH_AW_INFO_AGENT_VERSION environment variable
(symbol GH_AW_INFO_AGENT_VERSION) from "latest" to a specific semver (e.g.,
"vX.Y.Z") and likewise pin the Copilot CLI install step referenced around line
644 to a specific release tag instead of "latest"; update any relevant workflow
inputs/steps that reference those variables so they use the chosen pinned
versions consistently across the workflow.

In @.github/workflows/gh-aw-pr-review-addresser.lock.yml:
- Line 1868: The workflow's GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG now protects the
prefix protected_path_prefixes:[".github/"," .agents/"] which will cause pushes
to be rejected if the agent suggests changes under those paths, but the
user-facing prompt/guide still only tells the agent to avoid
".github/workflows/"; update the source prompt fragment (not this generated
.lock.yml) to include the full protected prefixes (e.g., ".github/" and
".agents/") so the agent is warned up-front, by editing the
documentation/fragment that produces the prompt to mention
protected_path_prefixes and to instruct the agent to avoid changes under
".github/" and ".agents/" (do not edit the compiled .lock.yml directly; change
the .md/fragment used by gh aw compile).

In @.github/workflows/gh-aw-release-update.lock.yml:
- Line 1681: The protected_path_prefixes in the
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG currently blocks patches under ".github/"
which prevents gh-aw-release-update from updating gh-aw-*.lock.yml workflow
refs; update the source fragment (not this generated .lock.yml) that defines
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG so that either the ".github/" prefix is
removed or made configurable and gh-aw-release-update is granted an explicit
opt-out (e.g., a flag on the create_pull_request config or a workflow-specific
exception) so create_pull_request in this workflow can modify files under
.github/workflows without being rejected; reference the
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG JSON, the create_pull_request object, the
protected_path_prefixes array and the gh-aw-release-update workflow when making
the change.

In @.github/workflows/gh-aw-scheduled-fix.lock.yml:
- Line 129: The lockfile defaulted GH_AW_INFO_AGENT_VERSION and the
install_copilot_cli.sh invocation to "latest", so update the source workflow
fragment that generates these values to pin a concrete version instead of
"latest": replace the GH_AW_INFO_AGENT_VERSION: "latest" setting with a specific
semver or tag and change the install_copilot_cli.sh call from
"install_copilot_cli.sh latest" to the same pinned version (ensure you update
the symbol GH_AW_INFO_AGENT_VERSION and the install_copilot_cli.sh argument),
then regenerate the lockfile so the lock reflects the pinned version.

In @.github/workflows/gh-aw-test-coverage-detector.lock.yml:
- Line 127: The workflow is using a floating Copilot CLI version ("latest") via
GH_AW_INFO_AGENT_VERSION and install_copilot_cli.sh which makes runs
nondeterministic; update the upstream source (the .md or imported fragment that
generates this workflow) to set a pinned version string instead of "latest"
(e.g., set GH_AW_INFO_AGENT_VERSION to the desired semver and change the
install_copilot_cli.sh argument accordingly), then re-run gh aw compile to
regenerate the .lock.yml so the change persists; do not edit the generated
.lock.yml directly.

---

Outside diff comments:
In @.github/workflows/agent-efficiency.lock.yml:
- Around line 83-93: The workflow lockfile shows GH_AW_INFO_AGENT_VERSION set to
"latest" and calls to install_copilot_cli.sh using "latest", which makes runs
non-deterministic; update the source workflow(s) (the .md files that gh aw
compile uses) to replace GH_AW_INFO_AGENT_VERSION: "latest" and any
install_copilot_cli.sh latest invocations with a concrete pinned version (or add
logic to resolve and export the resolved version at compile time) so the
compiled .lock.yml contains deterministic pinned values; ensure you modify the
variables in the source workflow(s) that define GH_AW_INFO_AGENT_VERSION and the
installer invocation rather than editing the generated .lock.yml directly.

---

Nitpick comments:
In @.github/workflows/gh-aw-autonomy-atomicity-analyzer.lock.yml:
- Line 121: This lockfile line shows GH_AW_INFO_AGENT_VERSION set to "latest"
but the correct fix is to update the source workflow .md frontmatter (not the
generated .lock.yml) to pin the Copilot CLI via engine.version; edit the source
.md workflow frontmatter to include engine.id: copilot and engine.version:
"0.0.422" (or your desired exact version) and then re-run gh aw compile to
regenerate the .lock.yml so the generated GH_AW_INFO_AGENT_VERSION is pinned
instead of "latest".

In @.github/workflows/gh-aw-bug-exterminator.lock.yml:
- Around line 582-583: The workflow currently uses an unpinned call "run:
/opt/gh-aw/actions/install_copilot_cli.sh latest" which makes PR generation
non-deterministic; to fix, update the source workflow Markdown (not this
generated .lock.yml) to replace "latest" with an explicit Copilot CLI version
string (e.g., a specific tag) and then recompile with gh aw compile so the
generated .github/workflows/*.lock.yml will reflect the pinned version; look for
the install step in the source .md that emits install_copilot_cli.sh and change
the argument from "latest" to the chosen pinned version.

In @.github/workflows/gh-aw-deep-research.lock.yml:
- Line 617: Replace the floating tag in the npm install command so the workflow
installs a fixed release of the Gemini CLI instead of `@latest`: change the string
'@google/gemini-cli@latest' used in the run step (the `npm install -g` command)
to a specific version (e.g. '@google/gemini-cli@X.Y.Z'), then
recompile/regenerate the workflow fragment so the deprecated alias and canonical
workflow remain in sync.

In @.github/workflows/gh-aw-duplicate-issue-detector.lock.yml:
- Line 114: Verify whether using a floating Copilot CLI version is intentional;
if you need deterministic workflows, replace GH_AW_INFO_AGENT_VERSION: "latest"
with a pinned version string (matching engine.version in the source
workflow/frontmatter) and update the source .md that generates this .lock.yml
(not the generated .github/workflows/*.lock.yml) so engine.version is pinned in
the source; ensure the pinned version value you choose matches the installed CLI
and update any engine.version references accordingly.

In @.github/workflows/gh-aw-internal-gemini-cli-web-search.lock.yml:
- Line 612: Replace the floating install "run: npm install -g
`@google/gemini-cli`@latest" with a pinned canonical version (e.g.
"@google/gemini-cli@<exact-version-or-sha>") so the workflow reproducibly
installs the same binary; ensure the chosen exact version matches the one used
in gh-aw-deep-research.lock.yml to keep both lock files compiling to the same
known CLI.

In @.github/workflows/gh-aw-mention-in-issue-by-id.lock.yml:
- Line 139: The workflow currently pins GH_AW_INFO_AGENT_VERSION to the string
"latest" and the Copilot CLI install step also uses "latest", which hurts
reproducibility; change GH_AW_INFO_AGENT_VERSION from "latest" to a specific
version tag or make it read from an environment/inputs variable with a
documented default, and update the Copilot CLI install script to consume that
same version variable (instead of hardcoded "latest") so both the
GH_AW_INFO_AGENT_VERSION and the Copilot install reference a
pinned/parameterized version (look for GH_AW_INFO_AGENT_VERSION and the Copilot
CLI install command to modify).

In @.github/workflows/gh-aw-mention-in-pr-by-id.lock.yml:
- Around line 142-150: The GH_AW_INFO_AGENT_VERSION env var in the
generate_aw_info step currently hardcodes "latest"; change the source
workflow/fragment or the compiler that produces this lockfile so it resolves the
Copilot CLI version at build time (the exact installed tag/semver from the
source fragment) and writes that concrete version into GH_AW_INFO_AGENT_VERSION
instead of "latest"; ensure the installer step that installs Copilot CLI uses
and persists the same resolved version so the generated .lock.yml contains the
reproducible CLI build rather than the literal "latest".

In @.github/workflows/gh-aw-mention-in-pr-no-sandbox.lock.yml:
- Line 148: Replace the floating "latest" pin for the Copilot CLI with a fixed,
explicit version and emit that resolved version into the
GH_AW_INFO_AGENT_VERSION variable instead of the string "latest"; update the
source workflow/fragment (the .md that generates the
.github/workflows/*.lock.yml via gh aw compile) so the installer step uses the
exact Copilot CLI version and the metadata key GH_AW_INFO_AGENT_VERSION records
that resolved version, ensuring the lockfile will be regenerated with the pinned
value rather than relying on runtime resolution.

In @.github/workflows/gh-aw-performance-profiler.lock.yml:
- Line 733: The workflow currently uses an unpinned installer invocation
"/opt/gh-aw/actions/install_copilot_cli.sh latest" which lowers reproducibility;
revert this change in the source .md that generates the lockfile by pinning the
Copilot CLI version (replace "latest" with the desired semver or specific tag)
and then regenerate the lockfile with "gh aw compile" so the
.github/workflows/gh-aw-performance-profiler.lock.yml reflects the pinned
installer; do not edit the .lock.yml directly.

In @.github/workflows/gh-aw-pr-actions-fixer.lock.yml:
- Line 589: The workflow currently calls install_copilot_cli.sh with the
unpinned "latest" (the run step invoking
/opt/gh-aw/actions/install_copilot_cli.sh latest) and GH_AW_INFO_AGENT_VERSION
is also set to "latest"; to fix, decide whether you want reproducible builds and
then either pin both places to a specific Copilot CLI version (replace "latest"
with the chosen version string) or add an explicit comment/justification and
keep them as "latest"; update the run invocation and GH_AW_INFO_AGENT_VERSION
usage to match the chosen approach so both are consistent.

In @.github/workflows/gh-aw-scheduled-audit.lock.yml:
- Line 131: Replace the non-reproducible "latest" pins with explicit version
strings: update the GH_AW_INFO_AGENT_VERSION environment variable to a specific
release (e.g., "vX.Y.Z") and change the Copilot CLI install step to install a
fixed Copilot CLI version instead of "latest"; locate the
GH_AW_INFO_AGENT_VERSION definition and the Copilot CLI install step in the
workflow and substitute concrete version numbers (or reference a variable that
is set from a source-controlled .md or lockfile) so CI runs are deterministic.

In @.github/workflows/gh-aw-text-auditor.lock.yml:
- Line 812: The workflow currently calls
"/opt/gh-aw/actions/install_copilot_cli.sh latest", which uses the floating
"latest" tag and harms reproducibility; update that invocation to a pinned
version string (e.g., replace "latest" with the tested release tag you want to
lock to) or, if intentionally using "latest", add a clear note in the
corresponding source documentation file explaining the choice and the
recommended pinned alternative for reproducible runs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5e62b5e5-764c-401b-8f4d-1791e91fc500

📥 Commits

Reviewing files that changed from the base of the PR and between 2601806 and 2160df4.

📒 Files selected for processing (71)
  • .github/aw/actions-lock.json
  • .github/workflows/agent-deep-dive.lock.yml
  • .github/workflows/agent-efficiency.lock.yml
  • .github/workflows/agentics-maintenance.yml
  • .github/workflows/gh-aw-agent-suggestions.lock.yml
  • .github/workflows/gh-aw-autonomy-atomicity-analyzer.lock.yml
  • .github/workflows/gh-aw-branch-actions-detective.lock.yml
  • .github/workflows/gh-aw-breaking-change-detect.lock.yml
  • .github/workflows/gh-aw-breaking-change-detector.lock.yml
  • .github/workflows/gh-aw-bug-exterminator.lock.yml
  • .github/workflows/gh-aw-bug-hunter.lock.yml
  • .github/workflows/gh-aw-code-duplication-detector.lock.yml
  • .github/workflows/gh-aw-code-duplication-fixer.lock.yml
  • .github/workflows/gh-aw-code-quality-audit.lock.yml
  • .github/workflows/gh-aw-code-simplifier.lock.yml
  • .github/workflows/gh-aw-create-pr-from-issue.lock.yml
  • .github/workflows/gh-aw-deep-research.lock.yml
  • .github/workflows/gh-aw-dependency-review.lock.yml
  • .github/workflows/gh-aw-docs-drift.lock.yml
  • .github/workflows/gh-aw-docs-patrol.lock.yml
  • .github/workflows/gh-aw-duplicate-issue-detector.lock.yml
  • .github/workflows/gh-aw-estc-actions-resource-not-accessible-detector.lock.yml
  • .github/workflows/gh-aw-estc-docs-patrol-external.lock.yml
  • .github/workflows/gh-aw-estc-docs-pr-review.lock.yml
  • .github/workflows/gh-aw-estc-downstream-health.lock.yml
  • .github/workflows/gh-aw-estc-newbie-contributor-patrol-external.lock.yml
  • .github/workflows/gh-aw-estc-pr-buildkite-detective.lock.yml
  • .github/workflows/gh-aw-flaky-test-investigator.lock.yml
  • .github/workflows/gh-aw-framework-best-practices.lock.yml
  • .github/workflows/gh-aw-information-architecture.lock.yml
  • .github/workflows/gh-aw-internal-gemini-cli-web-search.lock.yml
  • .github/workflows/gh-aw-internal-gemini-cli.lock.yml
  • .github/workflows/gh-aw-issue-fixer.lock.yml
  • .github/workflows/gh-aw-issue-triage.lock.yml
  • .github/workflows/gh-aw-mention-in-issue-by-id.lock.yml
  • .github/workflows/gh-aw-mention-in-issue-no-sandbox.lock.yml
  • .github/workflows/gh-aw-mention-in-issue.lock.yml
  • .github/workflows/gh-aw-mention-in-pr-by-id.lock.yml
  • .github/workflows/gh-aw-mention-in-pr-no-sandbox.lock.yml
  • .github/workflows/gh-aw-mention-in-pr.lock.yml
  • .github/workflows/gh-aw-newbie-contributor-fixer.lock.yml
  • .github/workflows/gh-aw-newbie-contributor-patrol.lock.yml
  • .github/workflows/gh-aw-performance-profiler.lock.yml
  • .github/workflows/gh-aw-plan.lock.yml
  • .github/workflows/gh-aw-pr-actions-detective.lock.yml
  • .github/workflows/gh-aw-pr-actions-fixer.lock.yml
  • .github/workflows/gh-aw-pr-ci-detective.lock.yml
  • .github/workflows/gh-aw-pr-labeler.lock.yml
  • .github/workflows/gh-aw-pr-review-addresser.lock.yml
  • .github/workflows/gh-aw-pr-review.lock.yml
  • .github/workflows/gh-aw-product-manager-impersonator.lock.yml
  • .github/workflows/gh-aw-project-summary.lock.yml
  • .github/workflows/gh-aw-refactor-opportunist.lock.yml
  • .github/workflows/gh-aw-release-update.lock.yml
  • .github/workflows/gh-aw-scheduled-audit.lock.yml
  • .github/workflows/gh-aw-scheduled-fix.lock.yml
  • .github/workflows/gh-aw-small-problem-fixer.lock.yml
  • .github/workflows/gh-aw-stale-issues-investigator.lock.yml
  • .github/workflows/gh-aw-stale-issues-remediator.lock.yml
  • .github/workflows/gh-aw-stale-issues.lock.yml
  • .github/workflows/gh-aw-test-coverage-detector.lock.yml
  • .github/workflows/gh-aw-test-improvement.lock.yml
  • .github/workflows/gh-aw-test-improver.lock.yml
  • .github/workflows/gh-aw-text-auditor.lock.yml
  • .github/workflows/gh-aw-text-beautifier.lock.yml
  • .github/workflows/gh-aw-update-pr-body.lock.yml
  • .github/workflows/gh-aw-ux-design-patrol.lock.yml
  • .github/workflows/internal-downstream-health.lock.yml
  • .github/workflows/upgrade-check.lock.yml
  • .github/workflows/workflow-patrol.lock.yml
  • Makefile
🚧 Files skipped from review as they are similar to previous changes (1)
  • Makefile

GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_pull_request\":{\"draft\":\"${{ inputs.draft-prs }}\",\"max\":1,\"max_patch_size\":10240},\"missing_data\":{},\"missing_tool\":{}}"
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_pull_request\":{\"draft\":\"${{ inputs.draft-prs }}\",\"max\":1,\"max_patch_size\":10240,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"]},\"missing_data\":{},\"missing_tool\":{}}"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Reject protected-path refactor issues before the agent starts editing.

Line 1721 now blocks PR creation for .github/ and .agents/, but Lines 371-388 still let this workflow pick any open refactor issue and implement it. A duplication issue rooted in those paths will consume the scheduled run doing local work and then fail only at create_pull_request. Add candidate filtering or an explicit early skip for protected-path issues before the agent starts changing files. Based on learnings, this .lock.yml is generated from the corresponding .md source, so make that change in the source workflow/fragment rather than this lockfile.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gh-aw-code-duplication-fixer.lock.yml at line 1721, Update
the source workflow/fragment (not the generated .lock.yml) that produces
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG so the issue-selection step (the job/step that
currently picks any open refactor issue—look for names like pick_candidate_issue
or select_candidate_issue) filters out or early-skips candidates whose changed
files match the protected_path_prefixes (".github/", ".agents/") before any
agent work starts; ensure the same protected_path_prefixes value used in
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG is applied to the candidate filtering logic so
protected-path duplication issues are rejected before edits begin.

GH_AW_INFO_MODEL: "${{ inputs.model }}"
GH_AW_INFO_VERSION: ""
GH_AW_INFO_AGENT_VERSION: "0.0.421"
GH_AW_INFO_AGENT_VERSION: "latest"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

gh-aw v0.56.0 release notes agent version latest

💡 Result:

gh-aw v0.56.0 release notes (GitHub Agentic Workflows)

Released: 2026-03-08 (tag v0.56.0, marked Latest on the release page). [1]

Highlights / What’s new

  • gh aw add-wizard schedule frequency picker (hourly/3-hourly/daily/weekly/monthly/custom cron). [1]
  • protected-files enforcement in safe outputs to prevent agents from modifying critical files (with a clear remediation message). [1]
  • Early size validation for repo-memory via a new push_repo_memory MCP tool. [1]
  • gh aw add now fetches remote workflow dependencies (e.g., dispatch-workflow dependencies / declared resources) automatically. [1]

Bug fixes / improvements

  • Security: git auth tokens are no longer written to .git/config; they’re passed via env vars to the fetch subprocess. [1]
  • Cleaner first-run experience for push_repo_memory and clearer gh aw compile help text. [1]

“Agent version” / latest

If by “agent version” you mean the Codex CLI version that gh-aw pins/uses in its embedded tooling stack, the repo changelog indicates a pinned Codex → 0.91.0 (alongside other tool version bumps). [2]

If you meant a different “agent” (Copilot CLI / Claude Code / MCP Gateway / etc.), tell me which one and I’ll pull the exact pinned version. [2]

Sources: [1] [2]


🏁 Script executed:

fd ".github/workflows/gh-aw-issue-triage.lock.yml" -x wc -l {}

Repository: elastic/ai-github-actions

Length of output: 51


🏁 Script executed:

cat -n .github/workflows/gh-aw-issue-triage.lock.yml | sed -n '110,130p'

Repository: elastic/ai-github-actions

Length of output: 1524


🏁 Script executed:

cat -n .github/workflows/gh-aw-issue-triage.lock.yml | sed -n '635,655p'

Repository: elastic/ai-github-actions

Length of output: 1449


🏁 Script executed:

find . -name "install_copilot_cli.sh" -type f

Repository: elastic/ai-github-actions

Length of output: 51


🏁 Script executed:

cat -n .github/workflows/gh-aw-issue-triage.lock.yml | sed -n '1,50p'

Repository: elastic/ai-github-actions

Length of output: 2118


🏁 Script executed:

find . -name "*.md" -path "*gh-aw-fragments*" | head -20

Repository: elastic/ai-github-actions

Length of output: 1234


🏁 Script executed:

find . -name "install_copilot_cli.sh" -o -name "*install*copilot*"

Repository: elastic/ai-github-actions

Length of output: 51


🏁 Script executed:

rg "install_copilot_cli" -i

Repository: elastic/ai-github-actions

Length of output: 51


🏁 Script executed:

cat .github/workflows/gh-aw-fragments/runtime-setup.md

Repository: elastic/ai-github-actions

Length of output: 3365


🏁 Script executed:

rg "GH_AW_INFO_AGENT_VERSION" .github/workflows/gh-aw-fragments/

Repository: elastic/ai-github-actions

Length of output: 51


🏁 Script executed:

find . -name "*gh-aw-issue-triage*" -type f

Repository: elastic/ai-github-actions

Length of output: 158


🏁 Script executed:

find . -name "*.md" -path "./.github/workflows/*" | grep -v fragments | grep -v ".lock"

Repository: elastic/ai-github-actions

Length of output: 3053


🏁 Script executed:

rg "GH_AW_INFO_AGENT_VERSION|install_copilot_cli" --type md

Repository: elastic/ai-github-actions

Length of output: 51


🏁 Script executed:

cat .github/workflows/gh-aw-issue-triage.md | head -150

Repository: elastic/ai-github-actions

Length of output: 6236


🏁 Script executed:

rg "latest|GH_AW_INFO_AGENT_VERSION|install_copilot_cli" .github/workflows/gh-aw-issue-triage.md

Repository: elastic/ai-github-actions

Length of output: 51


🏁 Script executed:

rg "install_copilot_cli|COPILOT.*VERSION" --type md -A 3 -B 3

Repository: elastic/ai-github-actions

Length of output: 51


🏁 Script executed:

head -200 .github/workflows/gh-aw-issue-triage.md | tail -100

Repository: elastic/ai-github-actions

Length of output: 4650


🏁 Script executed:

wc -l .github/workflows/gh-aw-issue-triage.md

Repository: elastic/ai-github-actions

Length of output: 112


🏁 Script executed:

cat .github/workflows/gh-aw-issue-triage.md | grep -i "latest\|agent.version\|copilot" -C 3

Repository: elastic/ai-github-actions

Length of output: 514


Pin GH_AW_INFO_AGENT_VERSION and Copilot CLI install to specific versions for reproducibility.

Lines 118 and 644 use "latest" while other tools in the same workflow are pinned (e.g., v0.23.0 for AWF on line 125). Update the source workflow definition to specify versions instead of moving targets.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gh-aw-issue-triage.lock.yml at line 118, Replace the
ambiguous "latest" with fixed version strings to ensure reproducible runs:
change the GH_AW_INFO_AGENT_VERSION environment variable (symbol
GH_AW_INFO_AGENT_VERSION) from "latest" to a specific semver (e.g., "vX.Y.Z")
and likewise pin the Copilot CLI install step referenced around line 644 to a
specific release tag instead of "latest"; update any relevant workflow
inputs/steps that reference those variables so they use the chosen pinned
versions consistently across the workflow.

GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"missing_data\":{},\"missing_tool\":{},\"push_to_pull_request_branch\":{\"if_no_changes\":\"warn\",\"max_patch_size\":10240},\"reply_to_pull_request_review_comment\":{\"max\":10},\"resolve_pull_request_review_thread\":{\"max\":\"${{ inputs.resolve-pull-request-review-thread-max }}\"}}"
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"missing_data\":{},\"missing_tool\":{},\"push_to_pull_request_branch\":{\"if_no_changes\":\"warn\",\"max_patch_size\":10240,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"]},\"reply_to_pull_request_review_comment\":{\"max\":10},\"resolve_pull_request_review_thread\":{\"max\":\"${{ inputs.resolve-pull-request-review-thread-max }}\"}}"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add matching protected-path guidance to this workflow's prompt.

Line 1868 now makes push_to_pull_request_branch reject .github/ and .agents/, but Lines 370-372 still only tell the agent to avoid .github/workflows/. Review threads on other protected paths will therefore end in a post-processing push rejection instead of an immediate “runtime blocked this change” explanation. Based on learnings: files under .github/workflows/*.lock.yml are auto-generated by gh aw compile, so fix this in the corresponding source .md/fragment rather than editing the lockfile directly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gh-aw-pr-review-addresser.lock.yml at line 1868, The
workflow's GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG now protects the prefix
protected_path_prefixes:[".github/"," .agents/"] which will cause pushes to be
rejected if the agent suggests changes under those paths, but the user-facing
prompt/guide still only tells the agent to avoid ".github/workflows/"; update
the source prompt fragment (not this generated .lock.yml) to include the full
protected prefixes (e.g., ".github/" and ".agents/") so the agent is warned
up-front, by editing the documentation/fragment that produces the prompt to
mention protected_path_prefixes and to instruct the agent to avoid changes under
".github/" and ".agents/" (do not edit the compiled .lock.yml directly; change
the .md/fragment used by gh aw compile).

GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_pull_request\":{\"draft\":\"${{ inputs.draft-prs }}\",\"max\":1,\"max_patch_size\":10240},\"missing_data\":{},\"missing_tool\":{}}"
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_pull_request\":{\"draft\":\"${{ inputs.draft-prs }}\",\"max\":1,\"max_patch_size\":10240,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"]},\"missing_data\":{},\"missing_tool\":{}}"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Don't protect .github/ in the release-update PR handler.

Line 1681 now blocks create_pull_request patches under .github/, but Lines 323-343 explicitly tell this workflow to update elastic/ai-github-actions/.github/workflows/gh-aw-*.lock.yml@... references. In the normal case those refs live in .github/workflows/**, so the runtime guard rejects the exact patch this workflow is supposed to create. Please exempt gh-aw-release-update from that shared guard or make the protected-path list configurable so this workflow can opt out.

Based on learnings, .lock.yml files under .github/workflows/ are generated by gh aw compile; apply the fix in the corresponding source .md/fragment, not in this lockfile.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gh-aw-release-update.lock.yml at line 1681, The
protected_path_prefixes in the GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG currently
blocks patches under ".github/" which prevents gh-aw-release-update from
updating gh-aw-*.lock.yml workflow refs; update the source fragment (not this
generated .lock.yml) that defines GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG so that
either the ".github/" prefix is removed or made configurable and
gh-aw-release-update is granted an explicit opt-out (e.g., a flag on the
create_pull_request config or a workflow-specific exception) so
create_pull_request in this workflow can modify files under .github/workflows
without being rejected; reference the GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG JSON,
the create_pull_request object, the protected_path_prefixes array and the
gh-aw-release-update workflow when making the change.

GH_AW_INFO_MODEL: "${{ inputs.model }}"
GH_AW_INFO_VERSION: ""
GH_AW_INFO_AGENT_VERSION: "0.0.421"
GH_AW_INFO_AGENT_VERSION: "latest"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Floating Copilot CLI references:"
rg -n -C2 'install_copilot_cli\.sh latest|GH_AW_INFO_AGENT_VERSION: "latest"' .

echo
echo "Pinned Copilot CLI references for comparison:"
rg -n -C2 'install_copilot_cli\.sh v[0-9]+' .

Repository: elastic/ai-github-actions

Length of output: 101


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find the source .md file for gh-aw-scheduled-fix
echo "=== Looking for source .md file ==="
fd -t f "gh-aw-scheduled-fix\.md"

# Check the .lock.yml file content around the lines in question
echo
echo "=== Content of .lock.yml at lines 129 and 609 ==="
sed -n '125,133p' .github/workflows/gh-aw-scheduled-fix.lock.yml
echo "---"
sed -n '605,613p' .github/workflows/gh-aw-scheduled-fix.lock.yml

Repository: elastic/ai-github-actions

Length of output: 1052


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# If source .md exists, check for 'latest' in it
if [ -f ".github/workflows/gh-aw-scheduled-fix.md" ]; then
  echo "=== Checking source .md for 'latest' ==="
  rg -n "latest" ".github/workflows/gh-aw-scheduled-fix.md" || echo "No 'latest' found in source"
  
  echo
  echo "=== Full content of source .md (or first 100 lines) ==="
  head -100 ".github/workflows/gh-aw-scheduled-fix.md"
fi

Repository: elastic/ai-github-actions

Length of output: 3212


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# List all .md files in .github/workflows to understand structure
echo "=== Available .md workflow files ==="
fd -t f "\.md$" ".github/workflows/"

Repository: elastic/ai-github-actions

Length of output: 4896


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check the runtime-setup fragment (likely location for CLI installation)
echo "=== Checking runtime-setup.md for 'latest' ==="
rg -n "latest" ".github/workflows/gh-aw-fragments/runtime-setup.md" || echo "No 'latest' found"

echo
echo "=== Checking scheduled-fix.md fragment ==="
rg -n "latest" ".github/workflows/gh-aw-fragments/scheduled-fix.md" || echo "No 'latest' found"

echo
echo "=== All fragments for 'latest' (comprehensive check) ==="
rg -n "latest" ".github/workflows/gh-aw-fragments/" || echo "No 'latest' found in any fragment"

Repository: elastic/ai-github-actions

Length of output: 287


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show context around 'latest' in runtime-setup.md if it exists
echo "=== Full content of runtime-setup.md (or first 150 lines) ==="
head -150 ".github/workflows/gh-aw-fragments/runtime-setup.md"

Repository: elastic/ai-github-actions

Length of output: 3427


Pin the agent version in the source workflow instead of defaulting to latest.

The lockfile contains GH_AW_INFO_AGENT_VERSION: "latest" and install_copilot_cli.sh latest, but these do not appear in the source .md file or any imported fragments. The compiler is generating latest as a default, which undermines reproducibility and makes debugging post-merge issues harder. Since .lock.yml files are auto-generated, the fix must be applied to .github/workflows/gh-aw-scheduled-fix.md by explicitly pinning the agent/CLI version.

Affects lines 129 and 609 in the lockfile.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gh-aw-scheduled-fix.lock.yml at line 129, The lockfile
defaulted GH_AW_INFO_AGENT_VERSION and the install_copilot_cli.sh invocation to
"latest", so update the source workflow fragment that generates these values to
pin a concrete version instead of "latest": replace the
GH_AW_INFO_AGENT_VERSION: "latest" setting with a specific semver or tag and
change the install_copilot_cli.sh call from "install_copilot_cli.sh latest" to
the same pinned version (ensure you update the symbol GH_AW_INFO_AGENT_VERSION
and the install_copilot_cli.sh argument), then regenerate the lockfile so the
lock reflects the pinned version.

GH_AW_INFO_MODEL: "${{ inputs.model }}"
GH_AW_INFO_VERSION: ""
GH_AW_INFO_AGENT_VERSION: "0.0.421"
GH_AW_INFO_AGENT_VERSION: "latest"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Inspect source and compiled workflow for floating Copilot CLI versions =="
while IFS= read -r file; do
  echo
  echo "--- $file ---"
  rg -n -C2 'GH_AW_INFO_AGENT_VERSION|install_copilot_cli\.sh' "$file" || true
done < <(fd 'gh-aw-test-coverage-detector\.(md|lock\.yml)$' .github/workflows -t f)

echo
echo "== Search for other floating Copilot CLI references in workflows =="
rg -n -C2 'GH_AW_INFO_AGENT_VERSION:\s*"latest"|install_copilot_cli\.sh latest' .github/workflows

Repository: elastic/ai-github-actions

Length of output: 219


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== List matching workflow files =="
fd 'gh-aw-test-coverage-detector\.(md|lock\.yml)$' .github/workflows -t f

echo
echo "== Check source .md file for floating Copilot CLI versions =="
if [ -f ".github/workflows/gh-aw-test-coverage-detector.md" ]; then
  echo "--- .github/workflows/gh-aw-test-coverage-detector.md ---"
  rg -n -C3 'GH_AW_INFO_AGENT_VERSION|install_copilot_cli' ".github/workflows/gh-aw-test-coverage-detector.md" || echo "(no matches)"
else
  echo "Source .md file not found"
fi

echo
echo "== Check lockfile for floating versions (lines around 127 and 744) =="
if [ -f ".github/workflows/gh-aw-test-coverage-detector.lock.yml" ]; then
  echo "--- Line 127 context ---"
  sed -n '124,130p' ".github/workflows/gh-aw-test-coverage-detector.lock.yml"
  echo
  echo "--- Line 744 context ---"
  sed -n '741,747p' ".github/workflows/gh-aw-test-coverage-detector.lock.yml"
else
  echo "Lockfile not found"
fi

Repository: elastic/ai-github-actions

Length of output: 1188


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Read source .md file (first 100 lines to see structure) =="
head -100 ".github/workflows/gh-aw-test-coverage-detector.md"

echo
echo "== Search for env/environment sections in source .md =="
rg -n -A5 -B2 'env:|GH_AW_INFO|install' ".github/workflows/gh-aw-test-coverage-detector.md" | head -80

echo
echo "== Total lines in source .md =="
wc -l ".github/workflows/gh-aw-test-coverage-detector.md"

Repository: elastic/ai-github-actions

Length of output: 4265


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check imported fragments that likely define runtime setup =="
for fragment in "gh-aw-fragments/runtime-setup.md" "gh-aw-fragments/elastic-tools.md"; do
  if [ -f "$fragment" ]; then
    echo "--- $fragment ---"
    echo "File exists. Searching for install_copilot_cli and GH_AW_INFO_AGENT_VERSION..."
    rg -n -C2 'install_copilot_cli|GH_AW_INFO_AGENT_VERSION' "$fragment" || echo "(no matches)"
    echo
  fi
done

echo "== List all gh-aw-fragments files =="
fd 'runtime.*\.md$' gh-aw-fragments -t f

Repository: elastic/ai-github-actions

Length of output: 289


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Find gh-aw-fragments directory =="
fd 'runtime-setup\.md' . -t f

echo
echo "== Find all .md files with similar names =="
fd 'runtime|setup' . -t f | head -20

echo
echo "== Check if fragments are in .github/workflows =="
ls -la .github/workflows/gh-aw-fragments/ 2>/dev/null || echo "Not in .github/workflows"

Repository: elastic/ai-github-actions

Length of output: 2797


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Read runtime-setup.md fragment =="
cat -n ".github/workflows/gh-aw-fragments/runtime-setup.md"

echo
echo "== Also check elastic-tools.md for related env vars =="
rg -n -C2 'GH_AW_INFO|install_copilot' ".github/workflows/gh-aw-fragments/elastic-tools.md" || echo "(no matches)"

Repository: elastic/ai-github-actions

Length of output: 4122


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Search ALL fragments for install_copilot_cli and GH_AW_INFO_AGENT_VERSION =="
rg -n 'install_copilot_cli|GH_AW_INFO_AGENT_VERSION' ".github/workflows/gh-aw-fragments/" || echo "(no matches in fragments)"

echo
echo "== Search the main source .md file more thoroughly =="
rg -n 'install_copilot_cli|GH_AW_INFO_AGENT_VERSION|agent_version|copilot' ".github/workflows/gh-aw-test-coverage-detector.md" || echo "(no matches)"

echo
echo "== Check git history: was this in the source before? =="
git log --oneline -20 -- ".github/workflows/gh-aw-test-coverage-detector.md" 2>/dev/null | head -5 || echo "(git history unavailable)"

echo
echo "== Check what changed in the lockfile in recent commits =="
git log --oneline -5 -- ".github/workflows/gh-aw-test-coverage-detector.lock.yml" 2>/dev/null || echo "(git history unavailable)"

Repository: elastic/ai-github-actions

Length of output: 511


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Show the commit that regenerated workflows =="
git show --stat 2160df4 | head -40

echo
echo "== Show the diff for the lockfile in that commit (snippet around GH_AW_INFO_AGENT_VERSION) =="
git show 2160df4 -- ".github/workflows/gh-aw-test-coverage-detector.lock.yml" 2>/dev/null | grep -A5 -B5 "GH_AW_INFO_AGENT_VERSION" | head -30 || echo "(could not extract)"

echo
echo "== Show the diff for the source .md file in that commit =="
git show 2160df4 -- ".github/workflows/gh-aw-test-coverage-detector.md" 2>/dev/null | head -100 || echo "(could not extract)"

Repository: elastic/ai-github-actions

Length of output: 2521


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check if other gh-aw workflows also have 'latest' for Copilot =="
rg -l 'install_copilot_cli\.sh latest' ".github/workflows/*.lock.yml" | head -5

echo
echo "== For one of them, check if the source .md has 'latest' =="
first_file=$(rg -l 'install_copilot_cli\.sh latest' ".github/workflows/*.lock.yml" | head -1)
if [ -n "$first_file" ]; then
  base_name=$(basename "$first_file" .lock.yml)
  source_file=".github/workflows/${base_name}.md"
  echo "Checking source: $source_file"
  if [ -f "$source_file" ]; then
    rg -n 'install_copilot_cli|latest' "$source_file" | head -10 || echo "(no matches)"
  fi
fi

echo
echo "== Check the gh-aw compiler itself or docs for default behavior =="
find . -name "*.md" -o -name "*.json" | xargs rg -l "gh-aw" | grep -i "readme\|docs\|guide" | head -5 || echo "(no docs found)"

Repository: elastic/ai-github-actions

Length of output: 222


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check if other gh-aw workflows also have 'latest' for Copilot =="
fd '\.lock\.yml$' '.github/workflows/' -t f | xargs rg -l 'install_copilot_cli\.sh latest' 2>/dev/null | head -5 || echo "(checking...)"

echo
echo "== Count how many workflows have install_copilot_cli.sh latest =="
fd '\.lock\.yml$' '.github/workflows/' -t f -x rg -c 'install_copilot_cli\.sh latest' {} \; | grep -v '^0$' | wc -l

echo
echo "== Show a few examples =="
fd '\.lock\.yml$' '.github/workflows/' -t f -x bash -c 'rg -l "install_copilot_cli\.sh latest" "$1" 2>/dev/null && echo "  Found in: $1"' _ {} \; | head -10

echo
echo "== For one example, check if source .md also uses latest =="
test_file=".github/workflows/gh-aw-bug-hunter.lock.yml"
if [ -f "$test_file" ]; then
  if rg -q 'install_copilot_cli\.sh latest' "$test_file"; then
    source_md="${test_file%.lock.yml}.md"
    echo "Source file: $source_md"
    if [ -f "$source_md" ]; then
      echo "Checking for 'latest' in source..."
      rg -n 'latest|install_copilot' "$source_md" || echo "(no matches in source)"
    fi
  fi
fi

Repository: elastic/ai-github-actions

Length of output: 442


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check if SOURCE .md files also contain 'latest' =="
# Get a sample of lockfiles with latest, convert to .md, and check if source has latest
fd '\.lock\.yml$' '.github/workflows/' -t f | while read lockfile; do
  if rg -q 'install_copilot_cli\.sh latest' "$lockfile" 2>/dev/null; then
    source_md="${lockfile%.lock.yml}.md"
    if [ -f "$source_md" ]; then
      if rg -q 'latest' "$source_md" 2>/dev/null; then
        echo "BOTH source and lockfile have 'latest': $(basename "$source_md")"
      else
        echo "ONLY lockfile has 'latest': $(basename "$source_md")"
      fi
    fi
  fi
done | sort | uniq -c | sort -rn

echo
echo "== Specifically check gh-aw-test-coverage-detector.md =="
rg -n 'latest|install_copilot_cli|GH_AW_INFO_AGENT' ".github/workflows/gh-aw-test-coverage-detector.md" || echo "(no matches)"

echo
echo "== Check git diff to see what actually changed in this PR =="
git diff HEAD~1 -- ".github/workflows/gh-aw-test-coverage-detector.md" 2>/dev/null | head -50 || echo "(diff unavailable)"

Repository: elastic/ai-github-actions

Length of output: 4130


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== This is significant: 62 lockfiles have 'latest' but source doesn't =="
echo "== This suggests gh aw v0.56.0 introduced 'latest' as a compiler default =="

echo
echo "== Check if there's a way to see what the previous pinned version was =="
# Check if any older lockfile snapshot exists or check git for older versions
git log --all --format='%H %s' -- ".github/workflows/gh-aw-test-coverage-detector.lock.yml" 2>/dev/null | head -3

echo
echo "== Try to see the parent commit's version of the lockfile =="
git show HEAD~1:".github/workflows/gh-aw-test-coverage-detector.lock.yml" 2>/dev/null | grep -A2 -B2 "install_copilot_cli" | head -10 || echo "(parent version unavailable)"

echo
echo "== Check the three .md files that DO have 'latest' in source to see if intentional =="
for file in ".github/workflows/upgrade-check.md" ".github/workflows/gh-aw-release-update.md" ".github/workflows/gh-aw-dependency-review.md"; do
  if [ -f "$file" ]; then
    echo "--- $file ---"
    rg -C2 'latest' "$file" | head -8
    echo
  fi
done

Repository: elastic/ai-github-actions

Length of output: 559


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Check if source files have any mechanism to pin Copilot CLI version =="
rg -n 'copilot.*version|install.*copilot' ".github/workflows/gh-aw-fragments/" -i | head -20

echo
echo "== See if there's any global configuration for Copilot version =="
find . -name "*.json" -o -name "*.yaml" -o -name "*.yml" | xargs rg -l 'copilot.*version|gh-aw' 2>/dev/null | grep -v '.lock.yml' | head -10

echo
echo "== Read the three source files that DO pin 'latest' intentionally =="
echo "--- upgrade-check.md ---"
rg -C3 'latest' ".github/workflows/upgrade-check.md" | head -15

echo
echo "--- gh-aw-release-update.md ---"
rg -C3 'latest' ".github/workflows/gh-aw-release-update.md" | head -15

Repository: elastic/ai-github-actions

Length of output: 142


Review gh-aw v0.56.0 compiler change: floating Copilot CLI version.

Line 127 sets GH_AW_INFO_AGENT_VERSION: "latest" and line 744 installs install_copilot_cli.sh latest. This makes the scheduled workflow's behavior nondeterministic across runs—the reported metadata and installed binary version will vary, complicating debugging and incident correlation.

This appears to be a default behavior introduced by the gh-aw v0.56.0 compiler bump in commit 2160df4 (affects 62+ regenerated workflows). The source .md file doesn't explicitly set these to latest, so this is compiler-generated. To override this default and pin the Copilot CLI version, modify the source .md or imported fragment, then recompile with gh aw compile. Per repository conventions, .lock.yml files are auto-generated and should not be edited directly.

Also applies to: 744-744

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/gh-aw-test-coverage-detector.lock.yml at line 127, The
workflow is using a floating Copilot CLI version ("latest") via
GH_AW_INFO_AGENT_VERSION and install_copilot_cli.sh which makes runs
nondeterministic; update the upstream source (the .md or imported fragment that
generates this workflow) to set a pinned version string instead of "latest"
(e.g., set GH_AW_INFO_AGENT_VERSION to the desired semver and change the
install_copilot_cli.sh argument accordingly), then re-run gh aw compile to
regenerate the .lock.yml so the change persists; do not edit the generated
.lock.yml directly.

@strawgate strawgate merged commit da60386 into main Mar 8, 2026
30 checks passed
@strawgate strawgate deleted the bill/upgrade-gh-aw-v0-56-0-protected-files branch March 8, 2026 06:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

medium_boom Medium PR blast radius; likely benefits from human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant