Skip to content

Propagate max-turn-cache-misses into the threat-detection job - #62489

Merged
pelikhan merged 4 commits into
mainfrom
copilot/fix-threat-detection-max-turn-cache-misses
Sep 22, 2026
Merged

pelikhan merged 4 commits into
mainfrom
copilot/fix-threat-detection-max-turn-cache-misses

Conversation

Copilot AI commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

The threat-detection job always compiled with the compile-time default maxCacheMisses (5): the detection EngineConfig is rebuilt from a fixed field list that omits MaxTurnCacheMisses, so buildAWFConfig resolved it through the nil/default path. Under BYOK providers that report cached_tokens only intermittently, detection then trips the AWF proxy's max_cache_misses_exceeded guard (HTTP 403) and — with threat-detection.continue-on-error: false — fails closed on every run carrying a real patch. The only existing lever was the GH_AW_DEFAULT_MAX_TURN_CACHE_MISSES compile env var.

Changes

  • pkg/workflow/threat_detection_helpers.go: new inheritDetectionTurnCacheMisses copies the workflow's top-level max-turn-cache-misses into the detection engine config when detection has no value of its own.
  • Both detection paths: called from buildDetectionEngineExecutionStep (inline) and buildExternalDetectorWorkflowData (external detector).
  • Locks: recompiled; the only diff is smoke-crush (the sole workflow setting the field), whose detection job now emits maxCacheMisses: 15 instead of 5.
  • Tests / docs / changeset: coverage for inheritance, default fallback, non-inheritance of max-turns, and the external-detector path; frontmatter reference notes the field also applies to detection.
# top-level frontmatter — now reaches the detection job's awf-config.json too
max-turn-cache-misses: 500

Note on max-turns

The issue suggested propagating max-runs "for consistency"; this PR deliberately does not. max-turns is a budget, and like max-ai-credits (which is explicitly not inherited today) detection keeps its own invocation cap so a tightly capped agent job cannot starve detection. The cache-miss guardrail is different in kind: it describes a property of the configured LLM provider, so it must apply to every job talking to that provider. Happy to extend to max-runs if reviewers prefer the symmetric behaviour.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix threat detection to utilize max-turn-cache-misses setting Propagate max-turn-cache-misses into the threat-detection job Sep 21, 2026
Copilot AI requested a review from pelikhan September 21, 2026 23:51
@pelikhan
pelikhan marked this pull request as ready for review September 21, 2026 23:52
Copilot AI balanced review requested due to automatic review settings September 21, 2026 23:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

The default-value subtest is environment-dependent and fails when the supported compiler override is set.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Propagates the workflow-level cache-miss guardrail to inline and external threat-detection jobs.

Changes:

  • Adds shared cache-miss inheritance logic.
  • Covers inheritance, defaults, and turn-cap separation.
  • Updates documentation, changeset, and generated workflow output.
File Description
pkg/​workflow/​threat_detection_inline_engine.go Applies inheritance to inline detection.
pkg/​workflow/​threat_detection_helpers.go Adds shared inheritance logic.
pkg/​workflow/​threat_detection_external_detector_config_test.go Tests external detection inheritance.
pkg/​workflow/​threat_detection_engine_test.go Tests inline inheritance and defaults.
docs/​src/​content/​docs/​reference/​frontmatter.md Documents detection behavior.
.github/​workflows/​smoke-crush.lock.yml Updates generated cache-miss limit.
.changeset/​detection-inherits-max-turn-cache-misses.md Records the patch change.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

}
})

t.Run("falls back to the compile default when the workflow does not configure it", func(t *testing.T) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in f87c5c6 by clearing compilerenv.DefaultMaxTurnCacheMisses in the default-cache-miss subtest before asserting the compile default.

@github-actions

github-actions Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ PR Code Quality Reviewer failed during code quality review.

Warning

Threat Detection Engine Failure — The analysis engine could not complete. This is a tooling failure, not a security finding.

What happened

The threat detection engine failed to produce results.

Review the workflow run logs for details.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

✅ Ponytail Reviewer completed successfully!

Lean already. Ship.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • ab.chatgpt.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "ab.chatgpt.com"

See Network Configuration for more information.

Generated by Ponytail Reviewer for #62489

@github-actions

github-actions Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

✅ Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel skipped because pre-fetch PR data was unavailable: unable to fetch test file diff

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ Security scanning failed for Design Decision Gate 🏗️. Review the logs for details.

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

Copy link
Copy Markdown
Contributor
🏗️ ADR Required — draft added for PR #62489

I added a draft ADR at docs/adr/62489-propagate-threat-detection-cache-miss-guardrail.md because this PR meets ADR enforcement by volume (102 added lines in default business-logic directories, above the 100-line threshold) and did not include an existing ADR with Michael Nygard sections.

Evidence used

  • Prefetch summary: has_implementation_label=false, default_business_additions=102, requires_adr_by_default_volume=true
  • PR title/body: this PR changes how threat-detection engine configuration is built and justified why max-turn-cache-misses should inherit while max-turns should not
  • Diff: code adds inheritDetectionTurnCacheMisses(...) in both inline and external detector paths, plus tests and frontmatter docs

Draft decision captured

  • Decision: inherit top-level max-turn-cache-misses into threat-detection jobs when detection does not set its own value
  • Driver: detection was always falling back to the compile-time default of 5, causing max_cache_misses_exceeded failures on providers that report cached tokens intermittently
  • Alternatives covered: keep the compile-time default behavior, or inherit all limits symmetrically including max-turns
  • Consequences covered: consistent provider guardrails across jobs, fewer fail-closed runs, added config coupling, and clearer docs/tests

Next action

Please review and update the draft ADR if needed, then keep it with the PR as the explicit design record for this architectural behavior change.

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · pi · gpt54 · 22.7 AIC · ⊞ 9.9K · ◷
Comment /review to run again

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot Please address the open Copilot review finding on this PR, then run the pr-finisher skill and update the branch. Open review item: Clear compiler environment override before testing default cache misses (#discussion_r4067417444). Also refresh the branch if needed after resolving review feedback.

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 13.1 AIC · ⊞ 9.3K · ◷
Comment /souschef to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Impeccable Skills Review

Modes applied: mixed_unclear → critique, audit (small internal compiler fix; no user-facing UI, so scored on correctness/consistency instead).

Summary

The change correctly propagates max-turn-cache-misses into the threat-detection job, mirroring the existing MaxAICredits-style inheritance pattern:

  • inheritDetectionTurnCacheMisses is nil-safe (data, data.EngineConfig, detectionConfig all guarded) and only fills in when the detection config doesn't already have a positive value — consistent with how max-turn-cache-misses is documented as top-level-only (no engine-config-level override exists in the schema), so there's no realistic clobbering risk.
  • Both call sites (buildDetectionEngineExecutionStep inline path, buildExternalDetectorWorkflowData external path) are covered, and the does not inherit max-turns regression test guards against accidentally coupling this to the unrelated max-turns budget precedent.
  • Docs and the single affected lock file (smoke-crush.lock.yml, maxCacheMisses 5→15) are consistent with the frontmatter change.
  • Build (go build ./...) and targeted tests (go test ./pkg/workflow/... threat-detection/engine-config suites) pass.

Notes

  • There's already an open review comment on threat_detection_engine_test.go:186 (from a prior pass) flagging that the "falls back to default" subtest doesn't guard against GH_AW_DEFAULT_MAX_TURN_CACHE_MISSES being set in the test environment. That's a valid, non-blocking robustness nit — not duplicating it here.

No additional blocking issues found in the changed lines.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • github.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "github.com"

See Network Configuration for more information.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · copilot · sonnet50 · 129 AIC · ⌖ 13.1 AIC · ⊞ 8.1K

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Skills-Based Review 🧠

Applied /diagnosing-bugs and /tdd to this bug fix. The core change (inheritDetectionTurnCacheMisses in pkg/workflow/threat_detection_helpers.go:226-243) is small, well-reasoned, and matches the pattern of the existing max-ai-credits handling — inherit only when the detection engine config has no explicit value of its own (<= 0), so overrides are respected. Verified by building and running go test ./pkg/workflow/... for the touched suites: all pass.

📋 Key Themes & Findings

Findings

  • A reviewer (Copilot) already flagged the one real issue I found: the new subtest "falls back to the compile default when the workflow does not configure it" (pkg/workflow/threat_detection_engine_test.go:186) asserts against the raw constants.DefaultMaxTurnCacheMisses constant, but the actual code path resolves through GetMaxTurnCacheMisses(), which honors GH_AW_DEFAULT_MAX_TURN_CACHE_MISSES. I reproduced this: running the suite with GH_AW_DEFAULT_MAX_TURN_CACHE_MISSES=9 set in the environment makes this specific subtest fail, while the sibling subtests pass. This is a real, reproducible test fragility (not just theoretical) in an enterprise deployment that sets this env var, or in CI that happens to inherit it. I'd support requesting a fix (e.g. wrap the expected value with compilerenv.ResolveDefaultMaxTurnCacheMisses(constants.DefaultMaxTurnCacheMisses) as done elsewhere in the codebase) before merge, per the existing comment.

Positive Highlights

  • ✅ Root cause is correctly identified and addressed at the source (buildAWFConfig / GetMaxTurnCacheMisses), not patched at the symptom.
  • ✅ Good regression-test coverage per /tdd: separate subtests for inheritance, default fallback, and explicit non-inheritance of max-runs, plus a matching test for the external-detector path.
  • ✅ The doc comment justifying why max-turns/max-runs is intentionally not inherited (unlike max-turn-cache-misses) is a nice touch — it preempts an obvious "why not do the same for max-runs" question and is consistent with the existing max-ai-credits precedent.
  • ✅ Lock-file diff is minimal and expected (only smoke-crush, the one workflow setting this field).

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet50 · 175.7 AIC · ⌖ 14.5 AIC · ⊞ 10.1K
Comment /matt to run again

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Sep 22, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Please address the open Copilot review finding on this PR, then run the pr-finisher skill and update the branch. Open review item: Clear compiler environment override before testing default c...

Addressed in f87c5c6. The default-cache-miss subtest now clears GH_AW_DEFAULT_MAX_TURN_CACHE_MISSES, and I ran the pr-finisher flow's local validation before updating the branch.

@pelikhan
pelikhan merged commit b27ae2e into main Sep 22, 2026
1 check passed
@pelikhan
pelikhan deleted the copilot/fix-threat-detection-max-turn-cache-misses branch September 22, 2026 01:34
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.89.20

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Threat detection ignores max-turn-cache-misses; detection always runs at the compile-time default (5)

4 participants