Summary
Recompiling an unchanged workflow from v0.87.1 to v0.87.2 moves the threat-detection job onto the external threat-detect implementation (now the default, #54111). Two properties of the detection job regressed in that swap, and neither is reachable from frontmatter:
- The detection execution step lost its step-level
timeout-minutes: 20. The detection job has no job-level timeout either, so the effective ceiling went from 20 minutes to the GitHub default of 360. - The detection job's AWF install dropped
--rootless, while the agent job in the same workflow kept it.
Both were found by diffing the compiled lock of one workflow whose .md source did not change at all — only the compiler version moved.
Environment
- gh-aw v0.87.1 → v0.87.2, AWF v0.28.2,
threat-detect v0.4.11, engine copilot - Agent job on a self-hosted 16-core runner; detection job on
ubuntu-latest via runs-on-slim - Frontmatter relevant to detection:
safe-outputs:
threat-detection:
engine:
id: copilotmodel: gpt-5.6-lunaprompt: >- ...continue-on-error: true
1. Detection execution is no longer time-bounded
v0.87.1 emitted the step timeout:
- name: Execute GitHub Copilot CLIif: always() && steps.detection_guard.outputs.run_detection == 'true'continue-on-error: trueid: detection_agentic_execution# Copilot CLI tool arguments (sorted):timeout-minutes: 20
v0.87.2 emits no timeout-minutes on the replacement step, only an env var for the binary to honour:
- name: Execute threat detection with AWFid: detection_agentic_executionif: always() && steps.detection_guard.outputs.run_detection == 'true'continue-on-error: trueenv:
...GH_AW_TIMEOUT_MINUTES: 20
grep -nE '^ timeout-minutes:' across the detection job returns nothing in either version, so in v0.87.1 the step timeout was the only bound and in v0.87.2 there is none. An internal timeout only helps once the process is far enough along to honour it; a wedge before that point — a stalled image pull, an AWF container that never comes up, or the copilot-sdk headless server did not become ready failure mode — now burns up to 6 hours of runner time instead of 20 minutes.
There is also no frontmatter lever. safe-outputs.threat-detection accepts only continue-on-error, enabled, engine, engine-config, environment, max-ai-credits, model, post-steps, prompt, runs-on and steps — no timeout key, and steps/post-steps cannot bound the compiler's own step.
Suggested fix: emit timeout-minutes: <GH_AW_TIMEOUT_MINUTES> on the execution step as before, or a job-level timeout-minutes on detection, so the bound does not depend on the binary reaching its own timeout logic.
2. --rootless is inconsistent between the agent and detection jobs
Same workflow, same compile. v0.87.1:
654: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.1 --rootless # agent
1759: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.1 --rootless # detection
v0.87.2:
670: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.2 --rootless # agent
1799: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.2 # detection
Both jobs then run the agent container through awf --config …, so it is not obvious why the install mode should differ. On a runner where rootless is required this would make detection fail while the agent job succeeds — a confusing split, and one that only shows up on hardened runners.
If the difference is deliberate — for instance because the detection job is expected on GitHub-hosted runners while the agent job may not be — it would help to say so in the generated comment, since the two lines are otherwise identical and invite the reader to assume one is a bug.
Impact for us
Low right now, because our threat-detection.continue-on-error: true turns a detection failure into a warning rather than a block, and because features.gh-aw-detection: false is available as a way back to the inline engine that still carries the step timeout. Filing it because the timeout in particular is a silent loosening that arrives with a routine version bump, on a job most users will never diff.
Summary
Recompiling an unchanged workflow from v0.87.1 to v0.87.2 moves the threat-detection job onto the external
threat-detectimplementation (now the default, #54111). Two properties of the detection job regressed in that swap, and neither is reachable from frontmatter:timeout-minutes: 20. The detection job has no job-level timeout either, so the effective ceiling went from 20 minutes to the GitHub default of 360.--rootless, while the agent job in the same workflow kept it.Both were found by diffing the compiled lock of one workflow whose
.mdsource did not change at all — only the compiler version moved.Environment
threat-detectv0.4.11, enginecopilotubuntu-latestviaruns-on-slim1. Detection execution is no longer time-bounded
v0.87.1 emitted the step timeout:
v0.87.2 emits no
timeout-minuteson the replacement step, only an env var for the binary to honour:grep -nE '^ timeout-minutes:'across thedetectionjob returns nothing in either version, so in v0.87.1 the step timeout was the only bound and in v0.87.2 there is none. An internal timeout only helps once the process is far enough along to honour it; a wedge before that point — a stalled image pull, an AWF container that never comes up, or thecopilot-sdk headless server did not become readyfailure mode — now burns up to 6 hours of runner time instead of 20 minutes.There is also no frontmatter lever.
safe-outputs.threat-detectionaccepts onlycontinue-on-error,enabled,engine,engine-config,environment,max-ai-credits,model,post-steps,prompt,runs-onandsteps— no timeout key, andsteps/post-stepscannot bound the compiler's own step.Suggested fix: emit
timeout-minutes: <GH_AW_TIMEOUT_MINUTES>on the execution step as before, or a job-leveltimeout-minutesondetection, so the bound does not depend on the binary reaching its own timeout logic.2.
--rootlessis inconsistent between the agent and detection jobsSame workflow, same compile. v0.87.1:
v0.87.2:
Both jobs then run the agent container through
awf --config …, so it is not obvious why the install mode should differ. On a runner where rootless is required this would make detection fail while the agent job succeeds — a confusing split, and one that only shows up on hardened runners.If the difference is deliberate — for instance because the detection job is expected on GitHub-hosted runners while the agent job may not be — it would help to say so in the generated comment, since the two lines are otherwise identical and invite the reader to assume one is a bug.
Impact for us
Low right now, because our
threat-detection.continue-on-error: trueturns a detection failure into a warning rather than a block, and becausefeatures.gh-aw-detection: falseis available as a way back to the inline engine that still carries the step timeout. Filing it because the timeout in particular is a silent loosening that arrives with a routine version bump, on a job most users will never diff.