You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
gh-aw still runs the inline threat-detection path in most compiled workflows: the detection job executes the agentic engine directly under AWF, scrapes THREAT_DETECTION_RESULT: out of detection.log with parse_threat_detection_results.cjs, and concludes with core.setOutput/core.setFailed. The external path (features: gh-aw-detection: true) downloads this repo's threat-detect binary and concludes via conclude_threat_detection.sh → threat-detect conclude.
Most recent relevant change upstream: github/gh-aw#48940 — engine failures (agent_failure, parse_error) now render as [!WARNING] threat detection engine error instead of [!CAUTION] agentic threat detected, keyed off isToolingFailureReason(reason). That makes the reason output load-bearing for user-facing severity, which raises the bar for our conclusion contract.
We made genuinely useful improvements when we diverged (out-of-band result sink instead of log scraping, trusted-vs-untrusted prompt analysis, structured JSONL run log, self-correction retries, an explicit terminal status line). This issue tracks everything that would regress if gh-aw flipped its workflows to this repo today.
prompt-template.txt / prompt-import-tree.json are never staged into the detection dir → the trusted-vs-untrusted prompt analysis, our flagship improvement, is a no-op in production
Conclusion logic duplicated across conclude_threat_detection.sh and threat-detect conclude; strict-mode missing-file branch writes noreason, which renders an infra failure as [!CAUTION] agentic threat detected — the exact bug #48940 fixed. Also an undocumented fail-closed divergence from ADR 29031's warn-mode resilience
threat-detect conclude emits far less diagnostic output than parse_threat_detection_results.cjs (no verdict breakdown, no input echo, no directory listing, no log stats)
Several items need a paired PR in github/gh-aw (staging step, execution-step env, external command flags, artifact upload paths). Those should be filed upstream and linked back here.
Definition of done
Every item above closed or explicitly waived with rationale recorded in specs/threat-detection-spec.md.
A side-by-side run of the same workflow on both paths produces equivalent job-log diagnostics, equivalent conclusion/reason/success outputs across the full failure matrix, and an equivalent (or better) verdict.
specs/threat-detection-spec.md and specs/usage-spec.md updated to describe the resulting contract normatively.
Context
gh-aw still runs the inline threat-detection path in most compiled workflows: the
detectionjob executes the agentic engine directly under AWF, scrapesTHREAT_DETECTION_RESULT:out ofdetection.logwithparse_threat_detection_results.cjs, and concludes withcore.setOutput/core.setFailed. The external path (features: gh-aw-detection: true) downloads this repo'sthreat-detectbinary and concludes viaconclude_threat_detection.sh→threat-detect conclude.Most recent relevant change upstream: github/gh-aw#48940 — engine failures (
agent_failure,parse_error) now render as[!WARNING] threat detection engine errorinstead of[!CAUTION] agentic threat detected, keyed offisToolingFailureReason(reason). That makes thereasonoutput load-bearing for user-facing severity, which raises the bar for our conclusion contract.We made genuinely useful improvements when we diverged (out-of-band result sink instead of log scraping, trusted-vs-untrusted prompt analysis, structured JSONL run log, self-correction retries, an explicit terminal status line). This issue tracks everything that would regress if gh-aw flipped its workflows to this repo today.
Audit scope
Reviewed against gh-aw @
main:pkg/workflow/threat_detection_{job,steps,inline_engine,external,config,helpers}.goactions/setup/js/{setup_threat_detection,parse_threat_detection_results,threat_detection_warning,messages_run_status,generate_footer}.cjsactions/setup/sh/{install_threat_detect_binary,conclude_threat_detection}.shactions/setup/md/{threat_detection,threat_warning_request_changes_review}.mddocs/src/content/docs/reference/threat-detection.md, ADRs 29031 / 29257 / 28160 / 38166 / 41231Findings
Blocking — features that are silently inert or fail-open today
prompt-template.txt/prompt-import-tree.jsonare never staged into the detection dir → the trusted-vs-untrusted prompt analysis, our flagship improvement, is a no-op in productionCUSTOM_PROMPT/WORKFLOW_NAME/WORKFLOW_DESCRIPTIONnever reach the detector →safe-outputs.threat-detection.promptis silently ignoredparse_erroris unreachable — everyTHREAT_DETECTION_STATUS:reason collapses toagent_failure, discarding the granularity #48940 depends onconclude_threat_detection.shandthreat-detect conclude; strict-mode missing-file branch writes noreason, which renders an infra failure as[!CAUTION] agentic threat detected— the exact bug #48940 fixed. Also an undocumented fail-closed divergence from ADR 29031's warn-mode resilienceDetection-coverage / accuracy regressions
{COMMENT_MEMORY_FILES}section dropped)aw_info.json(activation/trigger context) andexperiments/documented but never loadedObservability regressions
threat-detect concludeemits far less diagnostic output thanparse_threat_detection_results.cjs(no verdict breakdown, no input echo, no directory listing, no log stats)--log-file) is never enabled or uploadedaictoken-usage parsing unverified;max-ai-creditsbudget not enforced on the external pathPackaging
THREAT_DETECTION_RESULT:line emitted, so gh-aw's log-scraping fallback can never recover a verdictthreat-detect-darwin-*assets we never publishSuggested sequencing
threat-detect conclude, with divergent (and partly broken) semantics #694 + Parity:parse_erroris unreachable on the external path — THREAT_DETECTION_STATUS reasons are collapsed toagent_failure#693 first — they define the conclusion contract everything else reports through, and Parity: conclusion logic is duplicated in conclude_threat_detection.sh andthreat-detect conclude, with divergent (and partly broken) semantics #694 contains a live correctness bug.threat-detection.promptis silently ignored #688 + Parity: missing ERR_VALIDATION warnings — degraded/absent artifacts silently produce a clean verdict (fail-open) #701 — restore the inputs and make degradation loud. Without these the detector is running on far less context than the inline path.THREAT_DETECTION_RESULT:line, so gh-aw's detection-log fallback can never recover a verdict #695 — cheap resilience, no gh-aw change required.threat-detect concludeemits far less diagnostic output than parse_threat_detection_results.cjs #692 + Parity: step summary shows gh-aw's unused prompt; threat-detect contributes no prompt or verdict summary #696 + Parity: the structured JSONL run log (--log-file) is never enabled or uploaded on the external detector path #697 — observability, so the remaining items are diagnosable from a job log.aic) unverified andmax-ai-creditsbudget not enforced on the external detector path #698 + Parity: documented artifactsaw_info.jsonandexperiments/are never loaded or surfaced #704 + Parity: gh-aw's installer supports threat-detect-darwin-* assets that we never publish #702 — coverage, cost, and packaging.Several items need a paired PR in
github/gh-aw(staging step, execution-step env, external command flags, artifact upload paths). Those should be filed upstream and linked back here.Definition of done
specs/threat-detection-spec.md.conclusion/reason/successoutputs across the full failure matrix, and an equivalent (or better) verdict.specs/threat-detection-spec.mdandspecs/usage-spec.mdupdated to describe the resulting contract normatively.