Skip to content

eslint-factory: recognize JSDoc @param {typeof import('@actions/core')} as core-alias signal - #49502

Merged
pelikhan merged 5 commits into
mainfrom
copilot/eslint-factory-fix-core-aliases-gap
Aug 1, 2026
Merged

eslint-factory: recognize JSDoc @param {typeof import('@actions/core')} as core-alias signal#49502
pelikhan merged 5 commits into
mainfrom
copilot/eslint-factory-fix-core-aliases-gap

Conversation

Copilot AI commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

8 ESLint rules sharing core-method-resolve.ts were blind to DI-style @actions/core parameters with non-canonical names (e.g., coreArg) because isCoreAliasIdentifier only matched against CORE_ALIASES = {"core", "coreObj"}. Any function like async function f(coreArg, ctx) was invisible to all affected rules regardless of its JSDoc type annotation.

Changes

  • core-method-resolve.ts

    • Added JSDOC_CORE_PARAM_RE — matches @param {typeof import('@actions/core')} <name> in block comments (single- and double-quote variants).
    • Added hasJSDocCoreParamAnnotation(functionNode, paramName, sourceCode) — checks JSDoc before the function node and its parent VariableDeclaration (for function expressions).
    • Added isJSDocCoreParamInScope(identifier, sourceCode) — resolves an identifier through scope and checks for the annotation.
    • isCoreAliasIdentifier — Parameter branch now has two gates: CORE_ALIASES fast path, then JSDoc slow path. Existing exact-name semantics are fully preserved.
    • isDestructuredCoreMethodIdentifier — accepts destructuring from JSDoc-annotated core parameters (e.g., const { setFailed } = coreArg).
  • Tests — new it() groups in require-return-after-core-setfailed.test.ts and no-core-setoutput-non-string.test.ts covering:

    • Valid: corpus case coreArg.setFailed(msg); throw … recognized as compliant (not a false positive).
    • Invalid: missing control-transfer after coreArg.setFailed(…) is flagged with suggestion.
    • Negative: un-annotated coreArg without JSDoc remains unrecognized (false-positive guard).

Before / after

/**
 * @param {typeof import('@actions/core')} coreArg - GitHub Actions core library
 */
async function validateContextVariables(coreArg, ctx) {
  coreArg.setFailed(errorMessage);
  throw new Error(errorMessage);   // ← now recognized as compliant by require-return-after-core-setfailed
}

Parameters without the JSDoc type annotation continue to be ignored — broad prefix/regex matching is intentionally avoided.

…lve.ts

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

PR Triage

  • Category: bug | Risk: low | Priority: low
  • Score: 17/100 (impact 10 + urgency 5 + quality 2)
  • Recommended action: defer
  • Batch: wip-drafts

Note: Draft, no diff yet (still generating)

Generated by 🔧 PR Triage Agent · auto · 48.9 AIC · ⌖ 6.24 AIC · ⊞ 7.9K ·

…/core')} in core-method-resolve

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix CORE_ALIASES gap in core-method-resolve eslint-factory: recognize JSDoc @param {typeof import('@actions/core')} as core-alias signal Aug 1, 2026
Copilot AI requested a review from pelikhan August 1, 2026 07:18
@pelikhan
pelikhan marked this pull request as ready for review August 1, 2026 07:20
Copilot AI review requested due to automatic review settings August 1, 2026 07:20

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.

Pull request overview

Extends shared ESLint core-method resolution to recognize JSDoc-typed dependency-injection parameters.

Changes:

  • Adds JSDoc-based core parameter detection.
  • Adds direct-call coverage for two ESLint rules.
  • Regenerates an unrelated workflow lock file.
Show a summary per file
File Description
core-method-resolve.ts Adds JSDoc-aware alias resolution.
require-return-after-core-setfailed.test.ts Tests annotated setFailed calls.
no-core-setoutput-non-string.test.ts Tests annotated setOutput calls.
daily-byok-ollama-test.lock.yml Adds generated model and pricing configuration.

Review details

Tip

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

  • Files reviewed: 4/4 changed files
  • Comments generated: 4
  • Review effort level: Balanced

* in a JSDoc block-comment value. Used as an unambiguous signal that a parameter
* is a dependency-injected `@actions/core`-like object.
*/
const JSDOC_CORE_PARAM_RE = /@param\s*\{typeof\s+import\(['"]@actions\/core['"]\)\}\s+(\w+)/g;

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.

Fixed in 9cfa1fa — changed JSDOC_CORE_PARAM_RE to use ([$\w]+) so identifiers containing $ (e.g. $core) are captured correctly.

Comment on lines +84 to +87
// Slow path: JSDoc @param {typeof import('@actions/core')} annotation on
// the enclosing function is an unambiguous signal for DI-style parameters
// with non-canonical names (e.g. `coreArg`, `coreLib`).
return hasJSDocCoreParamAnnotation(def.node, identifier.name, sourceCode);

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.

Fixed in 9cfa1fa — the variable branch in isCoreAliasIdentifier now checks || isJSDocCoreParamInScope(declarator.init as TSESTree.Identifier, sourceCode) so const c = coreArg is recognized when coreArg is JSDoc-annotated.

const declarator = def.node as TSESTree.VariableDeclarator;
if (!declarator.init) return false;
if (declarator.id.type === AST_NODE_TYPES.ObjectPattern && declarator.init.type === AST_NODE_TYPES.Identifier && CORE_ALIASES.has(declarator.init.name)) {
if (declarator.id.type === AST_NODE_TYPES.ObjectPattern && declarator.init.type === AST_NODE_TYPES.Identifier && (CORE_ALIASES.has(declarator.init.name) || isJSDocCoreParamInScope(declarator.init, sourceCode))) {

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.

Added in 9cfa1fa and 60e26fa — both test files now include valid/invalid cases for const { setFailed } = coreArg (CJS) and const { setOutput } = coreArg (CJS), exercising the destructuring branch directly.

(umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}"
printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.43/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"targets\":{\"copilot\":{\"host\":\"host.docker.internal:11434\"}}},\"container\":{\"imageTag\":\"0.27.43,squid=sha256:26be5e0b8c8f4c41c8a59126b29bb5d80b07253597472ded2a16bdd75abcbf9d,agent=sha256:04e2d1987a565000a8f114b89d806ae7a3864dd4f944be65275b28c93d8690e6,api-proxy=sha256:d85f57975af5ea23af4996e41ed73fbc8f5b4a47402472bfe82e508f352cb0c1,cli-proxy=sha256:65c45ea2967984d0024f3df61bc71335658a77ede96c8d9665da7a5f33a795ab\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.43/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"defaultAiCreditsPricing\":{\"input\":0.000001,\"output\":0.000001},\"targets\":{\"copilot\":{\"host\":\"host.docker.internal:11434\"}},\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.43,squid=sha256:26be5e0b8c8f4c41c8a59126b29bb5d80b07253597472ded2a16bdd75abcbf9d,agent=sha256:04e2d1987a565000a8f114b89d806ae7a3864dd4f944be65275b28c93d8690e6,api-proxy=sha256:d85f57975af5ea23af4996e41ed73fbc8f5b4a47402472bfe82e508f352cb0c1,cli-proxy=sha256:65c45ea2967984d0024f3df61bc71335658a77ede96c8d9665da7a5f33a795ab\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"

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.

This lock file change cannot be reverted without breaking check-workflow-drift. The .md source is unchanged in this PR, but make recompile now generates the extended content (fallback pricing + model-routing policy) due to updates in the compilation tooling. The check-workflow-drift gate requires lock files to always match what compilation produces. The lock file stays in sync with the compiler output.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

No test files were added or modified in this PR. Test Quality Sentinel skipped.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR #49502 does not have the 'implementation' label and has 0 new lines of code in business logic directories (threshold: 100).

@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.

The JSDoc-based slow path is well-structured. Global regex lastIndex is correctly reset before each exec loop. def.node for Parameter defs correctly points to the enclosing function, so getCommentsBefore finds the JSDoc. Arrow-function assignments are handled by walking up to VariableDeclarator.parent. Test coverage is thorough: valid and invalid cases for both affected rules, including the double-quote variant and the un-annotated-parameter must-not-match case.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 20.3 AIC · ⌖ 8.88 AIC · ⊞ 5.3K

@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 — requesting changes on correctness gaps and missing test coverage.

Key Themes and Highlights

Key Themes

  • Regex \w+ excludes $ in param namesJSDOC_CORE_PARAM_RE won't match $core or _core-style parameters (already flagged inline at line 9).
  • Destructuring path has no test coverageisDestructuredCoreMethodIdentifier was extended to accept destructuring from JSDoc-annotated params, but neither test file exercises this path (flagged inline).
  • Reassignment blind spot undocumentedconst c = coreArg; c.setOutput(...) silently escapes all rules because scope lookup only follows Parameter defs, not variable assignments. A negative test and a note in the PR description would set expectations (flagged inline).
  • VariableDeclarator JSDoc path untestedconst f = function(coreArg) {} with JSDoc on the const is code-path present but has no test case.

Positive Highlights

  • Dual-gate strategy (fast path / slow path) is clean and well-documented
  • lastIndex = 0 reset before each exec on the shared g-flag regex prevents stateful bugs
  • Negative tests (un-annotated coreArg stays invisible) are a strong regression guard
  • Both single- and double-quote JSDoc variants are covered

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 36.8 AIC · ⌖ 7.56 AIC · ⊞ 7K
Comment /matt 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.

Verdict: Request changes — solid, well-tested fix but with real false-negative gaps and an unexplained unrelated file change.

💡 Themes and highlights

The core logic (two-gate isCoreAliasIdentifier, scope-based isJSDocCoreParamInScope) is sound and well-documented, and the new test coverage for the DI + JSDoc pattern is genuinely good (valid/invalid/negative cases across two rule test suites).

However:

  • Missed export function/export async function case — a pattern already used in this codebase (main() entrypoints) — because getCommentsBefore is only checked against the function node and its VariableDeclaration parent, never an ExportNamedDeclaration/ExportDefaultDeclaration wrapper. This silently defeats the annotation for a real, existing usage pattern.
  • The \w+ parameter-name regex excludes $ and other legal identifier characters, narrowing the very guarantee this PR is trying to widen (flagged by a prior reviewer as well).
  • The destructuring branch (isDestructuredCoreMethodIdentifier) gained JSDoc-alias support but has no direct test coverage exercising it (also flagged previously).
  • The bundled .github/workflows/daily-byok-ollama-test.lock.yml diff (fallback pricing + model routing policy) is unrelated to the stated ESLint fix and unexplained in the PR description — this should be reverted from this PR or justified separately (also flagged previously).

The export-wrapped function gap is a new, concrete finding that should be fixed before merge since it silently reintroduces the exact false-negative class this PR sets out to close.

🔎 Code quality review by PR Code Quality Reviewer · auto · 58.9 AIC · ⌖ 9.31 AIC · ⊞ 7.8K
Comment /review to run again

function hasJSDocCoreParamAnnotation(functionNode: TSESTree.Node, paramName: string, sourceCode: TSESLint.SourceCode): boolean {
const nodesToCheck: TSESTree.Node[] = [functionNode];
const parent = functionNode.parent;
if (parent?.type === AST_NODE_TYPES.VariableDeclarator && parent.parent) {

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.

JSDoc lookup misses a real, used pattern in this codebase: export function/export async function (e.g. main).

💡 Details

hasJSDocCoreParamAnnotation only checks comments before functionNode itself, and, when the parent is a VariableDeclarator, before the enclosing VariableDeclaration. It never checks a preceding ExportNamedDeclaration/ExportDefaultDeclaration wrapper. For:

/**
 * `@param` {typeof import('`@actions/core`')} coreArg
 */
export async function main(coreArg) { coreArg.setFailed("x"); }

sourceCode.getCommentsBefore(functionNode) returns an empty array because the JSDoc precedes the ExportNamedDeclaration, not the FunctionDeclaration node — so the annotation is silently ignored and the rule falls through to false-negative behavior. This pattern is already used elsewhere in this codebase (e.g. export async function main() fixtures in no-core-error-then-process-exitcode.test.ts), so this is a concrete gap, not a hypothetical one. Fix: also check functionNode.parent when it is an ExportNamedDeclaration/ExportDefaultDeclaration.

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.

Fixed in 60e26fahasJSDocCoreParamAnnotation now also pushes functionNode.parent onto nodesToCheck when the parent is an ExportNamedDeclaration or ExportDefaultDeclaration, so JSDoc before export async function main(coreArg) is correctly recognized. ESM valid and invalid test cases were added to both test files.

* in a JSDoc block-comment value. Used as an unambiguous signal that a parameter
* is a dependency-injected `@actions/core`-like object.
*/
const JSDOC_CORE_PARAM_RE = /@param\s*\{typeof\s+import\(['"]@actions\/core['"]\)\}\s+(\w+)/g;

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.

The \w+ parameter-name matcher silently rejects valid JS identifiers containing $ or Unicode letters.

💡 Details

JSDOC_CORE_PARAM_RE captures the JSDoc param name with (\w+), which is [A-Za-z0-9_]. Real, legal JS identifiers like $core, core$, or coréArg won't match, so a correctly-annotated function using such a name is silently treated as un-annotated — a false negative with no test coverage or fallback warning. Given the whole point of this PR is closing false-negative gaps for non-canonical parameter names, this narrows the fix's own guarantee. Consider [$\w]+ at minimum, or a broader identifier-safe character class.

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.

Fixed in 9cfa1faJSDOC_CORE_PARAM_RE now captures ([$\w]+) instead of (\w+) so identifiers with $ (e.g. $core) match correctly.

(umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}"
printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.43/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"targets\":{\"copilot\":{\"host\":\"host.docker.internal:11434\"}}},\"container\":{\"imageTag\":\"0.27.43,squid=sha256:26be5e0b8c8f4c41c8a59126b29bb5d80b07253597472ded2a16bdd75abcbf9d,agent=sha256:04e2d1987a565000a8f114b89d806ae7a3864dd4f944be65275b28c93d8690e6,api-proxy=sha256:d85f57975af5ea23af4996e41ed73fbc8f5b4a47402472bfe82e508f352cb0c1,cli-proxy=sha256:65c45ea2967984d0024f3df61bc71335658a77ede96c8d9665da7a5f33a795ab\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.43/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"defaultAiCreditsPricing\":{\"input\":0.000001,\"output\":0.000001},\"targets\":{\"copilot\":{\"host\":\"host.docker.internal:11434\"}},\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.43,squid=sha256:26be5e0b8c8f4c41c8a59126b29bb5d80b07253597472ded2a16bdd75abcbf9d,agent=sha256:04e2d1987a565000a8f114b89d806ae7a3864dd4f944be65275b28c93d8690e6,api-proxy=sha256:d85f57975af5ea23af4996e41ed73fbc8f5b4a47402472bfe82e508f352cb0c1,cli-proxy=sha256:65c45ea2967984d0024f3df61bc71335658a77ede96c8d9665da7a5f33a795ab\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"

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.

This generated workflow change (fallback pricing + full model-routing policy) is unrelated to the described ESLint fix and is bundled without explanation.

💡 Details

The PR description is entirely about core-method-resolve.ts JSDoc recognition, yet this lock file diff adds defaultAiCreditsPricing and a large models routing table to the daily BYOK Ollama test's firewall/proxy config. This is almost certainly a stale/regenerated artifact from running make recompile against a newer source template rather than an intentional part of this fix. Bundling unrelated generated changes into a focused PR makes it harder to review, bisect, and roll back independently — if this config change is wrong or has unintended effects on credit limits/model routing, it will be attributed to the wrong PR. Recommend reverting this file's changes here and letting it land in its own separate PR alongside whatever change actually motivates it (or confirming intentionally that this drift is expected).

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.

This lock file change cannot be reverted without breaking check-workflow-drift. The .md source is unchanged in this PR, but make recompile now generates the extended content due to updates in the compilation tooling. Keeping the lock file in sync with compilation is required by the tooling gate.

@pelikhan

pelikhan commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

Copilot AI and others added 2 commits August 1, 2026 08:05
- Fix JSDOC_CORE_PARAM_RE to capture [$\w]+ (supports $ in param names)
- Fix variable alias branch to check isJSDocCoreParamInScope (const c = coreArg)
- Add destructuring test coverage for JSDoc-annotated DI params
- Lock file stays compiled (daily-byok-ollama-test: recompile artifact, unchanged md source)

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…hen test coverage

- hasJSDocCoreParamAnnotation: also checks ExportNamedDeclaration/ExportDefaultDeclaration
  parent so JSDoc before `export async function f(coreArg)` is recognized
- Add esmRuleTester to require-return-after-core-setfailed and no-core-setoutput-non-string
- Add valid/invalid ESM test groups covering `export async function` with JSDoc-annotated params

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Aug 1, 2026

Copy link
Copy Markdown
Contributor Author

@copilot run pr-finisher skill

All review feedback addressed (commits 9cfa1fa and 60e26fa):

  • Regex $ supportJSDOC_CORE_PARAM_RE uses [$\w]+ to capture identifiers like $core.
  • Variable alias branchisCoreAliasIdentifier now calls isJSDocCoreParamInScope for the const c = coreArg pattern.
  • Destructuring test coverage — valid/invalid const { setFailed } = coreArg and const { setOutput } = coreArg cases added to both test files.
  • export async function wrapperhasJSDocCoreParamAnnotation now checks the ExportNamedDeclaration/ExportDefaultDeclaration parent so JSDoc before exported functions is recognized. ESM valid/invalid test groups added.
  • Lock file — cannot be reverted; make recompile generates the extended content from the updated compilation tooling and check-workflow-drift requires it to stay in sync. The .md source is unchanged in this PR.

Local validation: make agent-report-progress-no-test passes (zero lint errors, all lock files in sync). All 56 affected unit tests pass. CI re-trigger needed before merge.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot quick triage for this PR:

  • There are no failing checks in the compact candidate set, but the PR still has unresolved review feedback.
  • Please address the newest blocking review items first:
    1. Matt Pocock Skills Reviewer — broaden the JSDoc param-name matcher beyond \w+ so legal names like $core remain supported; review summary: https://github.com/github/gh-aw/actions/runs/30689563950
    2. PR Code Quality Reviewer — cover/export-wrap JSDoc on export function / export async function and add direct tests for destructuring and VariableDeclarator JSDoc paths; review summary: https://github.com/github/gh-aw/actions/runs/30689563972
    3. Revert or justify the unrelated .github/workflows/daily-byok-ollama-test.lock.yml change if it is still part of the branch diff.
  • After that, run the pr-finisher skill and summarize what changed.

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 24.4 AIC · ⌖ 8.51 AIC · ⊞ 8.1K ·
Comment /souschef to run again

@pelikhan
pelikhan merged commit fc33648 into main Aug 1, 2026
1 check failed
@pelikhan
pelikhan deleted the copilot/eslint-factory-fix-core-aliases-gap branch August 1, 2026 08:15
Copilot AI requested a review from gh-aw-bot August 1, 2026 08:15
Copilot stopped work on behalf of gh-aw-bot due to an error August 1, 2026 08:15
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.84.2

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.

eslint-factory: core-method-resolve.ts CORE_ALIASES gap makes 8 sibling rules blind to DI-style core parameter names

4 participants