Skip to content

fix(workflow): emit Setup Node.js in detection job for Copilot engine#28160

Merged
pelikhan merged 4 commits intomainfrom
copilot/fix-threat-detection-node-setup
Apr 23, 2026
Merged

fix(workflow): emit Setup Node.js in detection job for Copilot engine#28160
pelikhan merged 4 commits intomainfrom
copilot/fix-threat-detection-node-setup

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 23, 2026

The threat-detection job compiler never ran DetectRuntimeRequirements, so Copilot workflows got Setup Node.js in the main agent job but not in the detection job — causing node: command not found at the Execute GitHub Copilot CLI step on any runner without ambient Node, followed by No THREAT_DETECTION_RESULT found.

Claude and Codex are unaffected because their install steps bundle Setup Node.js via BuildStandardNpmEngineInstallSteps(..., includeNodeSetup=true, ...).

Changes

  • agentic_engine.go — New engineRequiresNodeDriver(engine) predicate: checks DriverProvider.GetDriverScriptName() != "". Interface-level rather than config-keyed so it catches Copilot's built-in default driver (not just explicit engine.driver overrides).

  • nodejs.go — New installStepsContainNodeSetup(steps) dedup guard: uses the same extractStepName matcher as JobManager.ValidateDuplicateSteps so it stays aligned with what the validator flags as duplicates. Prevents double-emitting Setup Node.js for Claude/Codex whose install steps already include it.

  • threat_detection.gobuildDetectionEngineExecutionStep:

    • Prepends GenerateNodeJsSetupStep() when engineRequiresNodeDriver && !installStepsContainNodeSetup.
    • Also preserves DriverScript in the detection engine config rebuild (was silently dropped, causing threat-detection-specific driver overrides to be ignored).
  • Lock files — All 200 workflows recompiled. Copilot-detection jobs gain a Setup Node.js block immediately before Install GitHub Copilot CLI; Claude/Codex detection jobs are unchanged.

# detection job — before
- name: Install GitHub Copilot CLI
  run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.21

# detection job — after
- name: Setup Node.js
  uses: actions/setup-node@...
  with:
    node-version: '24'
    package-manager-cache: false
- name: Install GitHub Copilot CLI
  run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.21

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw I0Qgy-tD2IC3 (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw util (http block)
  • https://api.github.com/orgs/test-owner/actions/secrets
    • Triggering command: /usr/bin/gh gh api /orgs/test-owner/actions/secrets --jq .secrets[].name -w actions/setup/js/node_modules/flatted/golang/pkg/flatted/flatted.go ck.yml cmd/gh-aw/capitabash cmd/gh-aw/comman--norc cmd/gh-aw/format--noprofile ache/go/1.25.8/x64/pkg/tool/linushow (http block)
  • https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq [.object.sha, .object.type] | @tsv --get-regexp ^remote\..*\.gh-resolved$ /usr/bin/git 2080024204/.githgit show 64/pkg/tool/linu--show-toplevel git rev-�� --show-toplevel 64/pkg/tool/linux_amd64/vet /usr/bin/git k/gh-aw/gh-aw/.gnode show /usr/bin/gh git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq [.object.sha, .object.type] | @tsv --show-toplevel ache/go/1.25.8/x-trimpath /tmp/go-build2940312451/b447/stringutil.test "prettier" --wrigit (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @tsv /home/REDACTED/work/gh-aw/gh-aw show 64/pkg/tool/linux_amd64/link '**/*.ts' '**/*.git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @tsv --show-toplevel /tmp/gh-aw-merge-1331156541/new.md /usr/bin/git efaultBranchFromtr efaultBranchFrom\n .cfg git rev-�� --show-toplevel git /usr/bin/git k/gh-aw/gh-aw config ache/go/1.25.8/x--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq [.object.sha, .object.type] | @tsv --show-toplevel git /usr/bin/git ithub/workflows/git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq [.object.sha, .object.type] | @tsv ithub/workflows/architecture-guardian.md config .cfg remote.origin.urgit (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v8
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq [.object.sha, .object.type] | @tsv --show-toplevel git /usr/bin/git /ref/tags/v9 config 64/pkg/tool/linu-m git rev-�� --show-toplevel 64/pkg/tool/linux_amd64/compile /usr/bin/git g_.a g/semverutil/semrev-parse 1/x64/bin/node git (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v9
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv --exclude-standard on ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet /../../.prettiergit erignore (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv -c=4 -nolocalimports -importcfg /tmp/go-build2940312451/b437/importcfg -pack /home/REDACTED/work/gh-aw/gh-aw/pkg/semverutil/semverutil.go /home/REDACTED/work/gh-aw/gh-aw/pkg/semverutil/semverutil_test.go -c ithub/workflows (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq [.object.sha, .object.type] | @tsv se 4180951/b216/vet.cfg de-user-docs-review.lock.yml tierignore (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv --get remote.origin.url /opt/hostedtoolcache/node/24.14.1/x64/bin/node k/gh-aw/gh-aw/.ggit -trimpath me: String!) { --show-toplevel /opt/hostedtoolcache/node/24.14.1/x64/bin/node /tmp�� vars.MY_VAR git /usr/bin/git /home/REDACTED/worgit rev-parse 86_64/bash git (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv sistency_InlinedImports1896946364/001/inlined-a.md rev-parse /usr/bin/git se 4180951/b100/vetrev-parse r: $owner, name:--show-toplevel git -C /home/REDACTED/work/gh-aw/gh-aw/.github/workflows rev-parse om/org1/repo1.git npx prettier --wgit (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv /prettier gcc /usr/bin/git -x c function-refacto--show-toplevel /usr/bin/git remo�� -v /usr/bin/gh /usr/bin/git k/gh-aw/gh-aw :latest kflows/developer--show-toplevel git (http block)
  • https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq [.object.sha, .object.type] | @tsv /tmp/gh-aw-test-runs/20260423-210454-18263/test-1915526391/.github/workflows rev-parse /usr/bin/git h3593519533/001'git h3593519533/001'rev-parse -importcfg git -C runs/20260423-210454-18263/test-3793895384 config /opt/hostedtoolcache/node/24.14.1/x64/bin/node remote.origin.urgit 4180951/b218/vetrev-parse st.lock.yml node (http block)
  • https://api.github.com/repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b
    • Triggering command: /usr/bin/gh gh api /repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b --jq [.object.sha, .object.type] | @tsv (http block)
    • Triggering command: /usr/bin/gh gh api /repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b --jq [.object.sha, .object.type] | @tsv th .prettierigno-errorsas (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v0.1.2
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq [.object.sha, .object.type] | @tsv --show-toplevel x_amd64/vet /opt/hostedtoolcache/node/24.14.1/x64/bin/node y-frontmatter.mdgit -s -w -X main.verev-parse x_amd64/vet /opt/hostedtoolcache/node/24.14.1/x64/bin/node /tmp�� needs.build.outputs.version x_amd64/vet /usr/bin/git k/gh-aw/gh-aw (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq [.object.sha, .object.type] | @tsv bility_SameInputSameOutput2834018376/001/stability-test.md ache/go/1.25.8/xconfig /usr/bin/git se rk eport.lock.yml git init�� ../../../.pretti--noprofile url /opt/hostedtoolcache/node/24.14.1/x64/bin/node 01 4180951/b188/vetrev-parse yml node (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq [.object.sha, .object.type] | @tsv 0312451/b462/types.test config 0312451/b462/importcfg.link remote.origin.urgit 4180951/b104/vetrev-parse .cfg VWw7VJguVlRAx/jNQYSQDdMsvnnTZDbyx2/zg1-jwF1IRoPasY5xy3c/9ezsDU_VWw7VJguVlRAx -C ry=1 l ache/node/24.14.1/x64/bin/node ithub/workflows 4180951/b210/vetrev-parse r: $owner, name:--show-toplevel git (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/1/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/1/artifacts --jq .artifacts[].name -f ect-url-default.lock.yml -f owner=github -f git -C k/gh-aw/gh-aw show kflows/pr-nitpick-reviewer.lock.yml ./../pkg/workflogit (http block)
    • Triggering command: /usr/bin/gh gh run download 1 --dir test-logs/run-1 erena-mcp-server:latest 64/pkg/tool/linux_amd64/vet remote.origin.urgit (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12345/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/12345/artifacts --jq .artifacts[].name erena-mcp-server:latest /usr/bin/git remote.origin.urgit (http block)
    • Triggering command: /usr/bin/gh gh run download 12345 --dir test-logs/run-12345 :latest /usr/bin/git -f owner=github -f git -C /home/REDACTED/work/gh-aw/gh-aw/.g-p config er: String!, $name: String!) { -lang=go1.25 remote.origin.urgit (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12346/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/12346/artifacts --jq .artifacts[].name rev-parse 86_64/bash json' --ignore-pgit (http block)
    • Triggering command: /usr/bin/gh gh run download 12346 --dir test-logs/run-12346 rev-parse ndor/bin/bash json' --ignore-pgit (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/2/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/2/artifacts --jq .artifacts[].name show 64/pkg/tool/linux_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh run download 2 --dir test-logs/run-2 :latest 64/pkg/tool/linux_amd64/vet remote.origin.urnode (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/3/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/3/artifacts --jq .artifacts[].name config 64/pkg/tool/linux_amd64/compile l (http block)
    • Triggering command: /usr/bin/gh gh run download 3 --dir test-logs/run-3 show 64/pkg/tool/linux_amd64/compile on' --ignore-patgit (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/4/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/4/artifacts --jq .artifacts[].name rev-parse 64/pkg/tool/linux_amd64/asm (http block)
    • Triggering command: /usr/bin/gh gh run download 4 --dir test-logs/run-4 rev-parse 64/pkg/tool/linux_amd64/vet on' --ignore-patgit (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/5/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/5/artifacts --jq .artifacts[].name show 64/pkg/tool/linux_amd64/cgo (http block)
    • Triggering command: /usr/bin/gh gh run download 5 --dir test-logs/run-5 rev-parse 64/pkg/tool/linux_amd64/vet on' --ignore-patgit (http block)
  • https://api.github.com/repos/github/gh-aw/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path 79414281/001' 79414281/001' .cfg (http block)
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 100 --ignore-path ../../../.pretti--pack_header=2,3 ache/go/1.25.8/x-q -uns�� ithub/workflows /tmp/go-build117-nolocalimports repository(owne-importcfg (http block)
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 6 (http block)
  • https://api.github.com/repos/github/gh-aw/contents/.github/workflows/shared/reporting.md
    • Triggering command: /tmp/go-build2940312451/b404/cli.test /tmp/go-build2940312451/b404/cli.test -test.testlogfile=/tmp/go-build2940312451/b404/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v0.47.4
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v0.47.4 --jq [.object.sha, .object.type] | @tsv --show-toplevel /usr/bin/gh /usr/bin/git 0454-18263/test-git -f ash git rev-�� --show-toplevel git /usr/bin/git 0454-18263/test-ls show /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq [.object.sha, .object.type] | @tsv /home/REDACTED/work/gh-aw/gh-aw show k ../pkg/workflow/git (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.2.3 --jq [.object.sha, .object.type] | @tsv ithub/workflows (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v2.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq [.object.sha, .object.type] | @tsv ithub/workflows (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq [.object.sha, .object.type] | @tsv --write ../../../**/*.json /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linu-f --ignore-path lang/pkg/flattedinit (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq [.object.sha, .object.type] | @tsv --write ../../../**/*.jsgithub.com/github/gh-aw/pkg/logger repository(owne-lang=go1.25 --ignore-path ../../../.pretti-C (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v3.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v3.0.0 --jq [.object.sha, .object.type] | @tsv ../../../**/*.json !../../../pkg/workflow/js/**/*.json ache/go/1.25.8/x64/pkg/tool/linux_amd64/asm ../../../.prettigh (http block)
  • https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq [.object.sha, .object.type] | @tsv k/gh-aw/gh-aw/.github/workflows (http block)
  • https://api.github.com/repos/nonexistent/repo/actions/runs/12345
    • Triggering command: /usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion (http block)
  • https://api.github.com/repos/owner/repo/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo .cfg (http block)
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo ml (http block)
    • Triggering command: /usr/bin/gh gh workflow list --repo owner/repo --json name,path,state /usr/bin/gh (http block)
  • https://api.github.com/repos/test-owner/test-repo/actions/secrets
    • Triggering command: /usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name se 4180951/b229/vet.cfg .cfg (http block)
  • https://api.github.com/repos/test/repo
    • Triggering command: /usr/bin/gh gh api /repos/test/repo --jq .default_branch 1203729943 .cfg (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title [WIP] Fix threat-detection job to properly setup Node.js fix(workflow): emit Setup Node.js in detection job for Copilot engine Apr 23, 2026
Copilot AI requested a review from pelikhan April 23, 2026 21:12
@github-actions
Copy link
Copy Markdown
Contributor

Great work on this fix, @Copilot! 🎉 The threat-detection Node.js setup bug is clearly addressed with well-scoped helpers (engineRequiresNodeDriver, installStepsContainNodeSetup), a targeted fix in buildDetectionEngineExecutionStep, and 3 new test functions covering the new logic. The lock file regeneration is properly accounted for. This PR looks ready for maintainer review!

Generated by Contribution Check · ● 1.8M ·

@pelikhan pelikhan marked this pull request as ready for review April 23, 2026 21:47
Copilot AI review requested due to automatic review settings April 23, 2026 21:47
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 23, 2026

Smoke CI completed successfully!

@github-actions
Copy link
Copy Markdown
Contributor

✅ smoke-ci: safeoutputs CLI comment + comment-memory run (24860555484)

Generated by Smoke CI for issue #28160 ·

@github-actions
Copy link
Copy Markdown
Contributor

Comment Memory

`````` CI lights the path\nGreen checks bloom at dawn\nQuiet bots still sing ``````

Note

This comment is managed by comment memory.

What this comment does

It stores persistent context for this thread in the <gh-aw-comment-memory> block at the top of this comment.
Edit only the text in that block; workflow metadata and the footer are regenerated automatically.

Generated by Smoke CI for issue #28160 ·

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes Copilot threat-detection workflow compilation so the detection job reliably has Node.js available when Copilot execution is wrapped by a Node-based driver script, and ensures threat-detection driver overrides aren’t dropped.

Changes:

  • Add engineRequiresNodeDriver(engine) predicate to detect engines that wrap execution with a Node-launched driver script.
  • Emit Setup Node.js in the threat-detection job when needed, with a dedup guard aligned to duplicate-step validation.
  • Preserve DriverScript when rebuilding the detection-job engine config; recompile workflow lockfiles to reflect the new step.
Show a summary per file
File Description
pkg/workflow/agentic_engine.go Introduces engineRequiresNodeDriver helper based on DriverProvider.
pkg/workflow/nodejs.go Adds installStepsContainNodeSetup guard using extractStepName to avoid duplicate Setup Node.js.
pkg/workflow/threat_detection.go Preserves DriverScript in detection config rebuild; prepends Node setup in detection job when required.
pkg/workflow/threat_detection_test.go Adds tests covering Node setup emission/dedup and driver script override propagation.
.github/workflows/workflow-health-manager.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/workflow-generator.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/video-analyzer.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/ubuntu-image-analyzer.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/test-quality-sentinel.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/test-project-url-default.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/test-dispatcher.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/technical-doc-writer.lock.yml Recompiled lockfile; detection job gains Setup Node.js.
.github/workflows/sub-issue-closer.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/smoke-workflow-call.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/smoke-test-tools.lock.yml Recompiled lockfile; detection job gains Setup Node.js.
.github/workflows/security-compliance.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/research.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/repo-tree-map.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/refiner.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/pr-triage-agent.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/mcp-inspector.lock.yml Recompiled lockfile; detection job gains Setup Node.js.
.github/workflows/jsweep.lock.yml Recompiled lockfile; detection job gains Setup Node.js.
.github/workflows/issue-triage-agent.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/github-remote-mcp-auth-test.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/draft-pr-cleanup.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/docs-noob-tester.lock.yml Recompiled lockfile; detection job gains Setup Node.js.
.github/workflows/discussion-task-miner.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/dictation-prompt.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/dev.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/dependabot-go-checker.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/dependabot-burner.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/delight.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/daily-secrets-analysis.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/daily-news.lock.yml Recompiled lockfile; detection job gains Setup Node.js.
.github/workflows/daily-issues-report.lock.yml Recompiled lockfile; detection job gains Setup Node.js.
.github/workflows/daily-hippo-learn.lock.yml Recompiled lockfile; detection job gains Setup Node.js.
.github/workflows/daily-cli-performance.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/craft.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/copilot-token-audit.lock.yml Recompiled lockfile; detection job gains Setup Node.js.
.github/workflows/copilot-pr-merged-report.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/copilot-cli-deep-research.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/contribution-check.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/cli-consistency-checker.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/ci-coach.lock.yml Recompiled lockfile; detection job gains Setup Node.js.
.github/workflows/breaking-change-checker.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/auto-triage-issues.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/artifacts-summary.lock.yml Recompiled lockfile; detection job gains Setup Node.js (and manifest includes setup-node).
.github/workflows/agentic-optimization-kit.lock.yml Recompiled lockfile; detection job gains Setup Node.js.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 123/123 changed files
  • Comments generated: 1

Comment on lines 508 to 517
detectionEngineConfig = &EngineConfig{
ID: detectionEngineConfig.ID,
Model: detectionEngineConfig.Model,
Version: detectionEngineConfig.Version,
Env: detectionEngineConfig.Env,
Config: detectionEngineConfig.Config,
Args: detectionEngineConfig.Args,
APITarget: detectionEngineConfig.APITarget,
ID: detectionEngineConfig.ID,
Model: detectionEngineConfig.Model,
Version: detectionEngineConfig.Version,
Env: detectionEngineConfig.Env,
Config: detectionEngineConfig.Config,
Args: detectionEngineConfig.Args,
APITarget: detectionEngineConfig.APITarget,
DriverScript: detectionEngineConfig.DriverScript,
}
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

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

When rebuilding detectionEngineConfig, the new struct copies ID from the source config. If the caller provided an EngineConfig with overrides (e.g. Version/Model) but left ID empty, this rebuild keeps ID empty, which can cause downstream logic that relies on EngineConfig.ID to misbehave (and can diverge from the resolved engineSetting). Consider setting ID to engineSetting when the copied ID is empty (or always set ID: engineSetting here).

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 80/100

Excellent test quality

Metric Value
New/modified tests analyzed 3
✅ Design tests (behavioral contracts) 3 (100%)
⚠️ Implementation tests (low value) 0 (0%)
Tests with error/edge cases 2 (67%)
Duplicate test clusters 0
Test inflation detected Yes (158 test lines added vs 21 production lines in threat_detection.go, ~7.5:1 ratio)
🚨 Coding-guideline violations None

Test Classification Details

View all 3 tests
Test File Classification Issues Detected
TestBuildDetectionEngineExecutionStepEmitsNodeSetupForCopilot pkg/workflow/threat_detection_test.go:1620 ✅ Design None — covers 4 engine variants including duplication guard
TestInstallStepsContainNodeSetup pkg/workflow/threat_detection_test.go:1712 ✅ Design None — covers nil input, canonical step, indentation tolerance
TestBuildDetectionEngineExecutionStepPropagatesDriverScriptOverride pkg/workflow/threat_detection_test.go:1763 ✅ Design Happy-path only; no error case (driver absent or empty)

Flagged Tests — Requires Review

i️ TestBuildDetectionEngineExecutionStepPropagatesDriverScriptOverride

Classification: Design test (behavioral contract) — no issues blocking merge
Minor observation: This test only covers the happy path (custom driver present). Consider adding a row for the zero-value case (DriverScript: ""), confirming that the default actions/copilot_driver.cjs is emitted instead. This would prevent a future regression where an empty override silently suppresses the default driver.


Language Support

Tests analyzed:

  • 🐹 Go (*_test.go): 3 tests — unit (//go:build !integration)
  • 🟨 JavaScript (*.test.cjs, *.test.js): 0 tests

Verdict

Check passed. 0% of new tests are implementation tests (threshold: 30%). All three tests verify observable YAML output (step names, ordering, content) and exercise meaningful scenario variation via table-driven patterns. The only note is test inflation (158 test lines vs 21 production lines), which is a consequence of thorough table-driven coverage rather than waste — no penalty to the overall quality verdict.


📖 Understanding Test Classifications

Design Tests (High Value) verify what the system does:

  • Assert on observable outputs, return values, or state changes
  • Cover error paths and boundary conditions
  • Would catch a behavioral regression if deleted
  • Remain valid even after internal refactoring

Implementation Tests (Low Value) verify how the system does it:

  • Assert on internal function calls (mocking internals)
  • Only test the happy path with typical inputs
  • Break during legitimate refactoring even when behavior is correct
  • Give false assurance: they pass even when the system is wrong

Goal: Shift toward tests that describe the system's behavioral contract — the promises it makes to its users and collaborators.

References: §24860557410

🧪 Test quality analysis by Test Quality Sentinel · ● 488K ·

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

✅ Test Quality Sentinel: 80/100. Test quality is excellent — 0% of new tests are implementation tests (threshold: 30%). All 3 new tests verify behavioral contracts via table-driven patterns with meaningful scenario variation.

… threat detection job

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

Commit pushed: 5b5d0d1

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions
Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

This PR makes significant changes to core business logic (209 new lines in pkg/) but does not have a linked Architecture Decision Record (ADR).

AI has analyzed the PR diff and generated a draft ADR to help you get started:

📄 Draft ADR: docs/adr/28160-interface-level-node-driver-detection-for-threat-detection-job.md

What the draft covers

The ADR captures the key architectural decision in this PR: using interface-level detection (DriverProvider type assertion + GetDriverScriptName()) rather than config-keyed flags or engine type-switches to determine whether the threat detection job needs an explicit Setup Node.js step.

It also covers:

  • The installStepsContainNodeSetup dedup guard (reuses extractStepName from ValidateDuplicateSteps)
  • The DriverScript field preservation fix in the detection engine config rebuild
  • Consequences: auto-scales to future DriverProvider engines, but implicit Node.js assumption is undocumented at the interface boundary

What to do next

  1. Review the draft ADR committed to your branch
  2. Complete any missing context the AI couldn't infer (e.g., whether alternative approaches were explicitly considered during design)
  3. Reference the ADR in this PR body by adding a line such as:

    ADR: ADR-28160: Interface-Level Node Driver Detection for the Threat Detection Job

Once an ADR is linked in the PR body, this gate will re-run and verify the implementation matches the decision.

📋 Michael Nygard ADR Format Reference

An ADR must contain these four sections to be considered complete:

  • Context — What is the problem? What forces are at play?
  • Decision — What did you decide? Why?
  • Alternatives Considered — What else could have been done?
  • Consequences — What are the trade-offs (positive and negative)?

All ADRs are stored in docs/adr/ as Markdown files numbered by PR number (e.g., 28160-...md for PR #28160).

🔒 This PR cannot merge until an ADR is linked in the PR body.

References: §24860557400

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · ● 154.7K ·

@pelikhan pelikhan merged commit 36e5c36 into main Apr 23, 2026
@pelikhan pelikhan deleted the copilot/fix-threat-detection-node-setup branch April 23, 2026 21:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Threat-detection job omits Setup Node.js but launches copilot_driver.cjs via node → 'node: command not found'

3 participants