Skip to content

Handle required-workflow daily AIC guardrail lookups and expose structural failure state - #49961

Merged
pelikhan merged 8 commits into
mainfrom
copilot/fix-daily-ai-credits-guardrail
Aug 3, 2026
Merged

Handle required-workflow daily AIC guardrail lookups and expose structural failure state#49961
pelikhan merged 8 commits into
mainfrom
copilot/fix-daily-ai-credits-guardrail

Conversation

Copilot AI commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Organization-level required workflows can execute in a repository without being members of that repository’s workflow collection. In that case, the daily AI Credits guardrail resolved the current run successfully, then 404ed when querying run history by workflow_id, permanently failing open and making that structural failure indistinguishable from a transient skip.

  • Run-history lookup fallback

    • Keep the existing workflow_id query as the primary path.
    • On 404, fall back to repository-level run listing and filter by workflow name, so required-workflow injection still produces a usable 24h run window.
    • Preserve pagination behavior in fallback mode, including pages that contain zero matches but are not yet exhausted.
  • Structural vs transient failure signaling

    • Add daily_ai_credits_guardrail_status output to distinguish:
      • under_budget
      • exceeded
      • transient_error
      • structural_error
      • skipped / disabled / not_run
    • Keep fail-open behavior for unexpected runtime/API faults, but stop collapsing permanent 404 conditions into the same state as transient errors.
  • Focused guardrail regression coverage

    • Cover the required-workflow shape where:
      • getWorkflowRun() succeeds for the current run
      • listWorkflowRuns({ workflow_id }) returns 404
      • repository-level run history contains matching runs by workflow name
    • Cover the case where both lookup paths 404, asserting a structural error state rather than a generic transient skip.
try {
  return await githubClient.rest.actions.listWorkflowRuns({
    owner,
    repo,
    workflow_id: workflowId,
    status: "completed",
    per_page: perPage,
    page,
  });
} catch (error) {
  if (hasHttpStatus(error, 404) && workflowName) {
    const response = await githubClient.rest.actions.listWorkflowRunsForRepo({
      owner,
      repo,
      status: "completed",
      per_page: perPage,
      page,
    });
    response.data.workflow_runs = (response.data.workflow_runs || []).filter(
      run => run.name === workflowName
    );
    return response;
  }
  throw error;
}

run: https://github.com/github/gh-aw/actions/runs/30815680828

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 9.88 AIC · ⌖ 4.97 AIC · ⊞ 8.3K ·
Comment /souschef to run again


Run: https://github.com/github/gh-aw/actions/runs/30820387900

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 13.2 AIC · ⌖ 5.18 AIC · ⊞ 8.3K ·
Comment /souschef to run again


branch-refresh requested by PR Sous Chef run: https://github.com/github/gh-aw/actions/runs/30830929419

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 12 AIC · ⌖ 5.86 AIC · ⊞ 8.3K ·
Comment /souschef to run again

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix daily AI credits guardrail failing open for org-level workflows Handle required-workflow daily AIC guardrail lookups and expose structural failure state Aug 3, 2026
Copilot AI requested a review from pelikhan August 3, 2026 12:22
@pelikhan
pelikhan marked this pull request as ready for review August 3, 2026 12:30
Copilot AI review requested due to automatic review settings August 3, 2026 12:30
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

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

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

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

No ADR enforcement needed: PR does not have the 'implementation' label and has ≤100 new lines of code in business logic directories.

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

Adds required-workflow fallback handling and distinct guardrail execution statuses.

Changes:

  • Falls back to repository run history on workflow-specific 404s.
  • Distinguishes structural, transient, skipped, disabled, and budget states.
  • Adds focused regression tests for fallback pagination and structural errors.
Show a summary per file
File Description
actions/setup/js/check_daily_aic_workflow_guardrail.cjs Implements fallback lookup and status reporting.
actions/setup/js/check_daily_aic_workflow_guardrail.test.cjs Tests fallback and status behavior.

Review details

Tip

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

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

core.setOutput("daily_ai_credits_exceeded", "false");
core.setOutput("daily_ai_credits_total_effective_tokens", "");
core.setOutput("daily_ai_credits_threshold", "");
core.setOutput("daily_ai_credits_guardrail_status", "not_run");

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 commit c2a8e33daily_ai_credits_guardrail_status is now wired as a 4th activation-job output in compiler_activation_outputs.go alongside the three existing guardrail outputs, golden test snapshots updated, and TestDailyAICWorkflowGuardrailInCompiledWorkflow asserts the new output.

@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 implementation is correct and well-structured.

  • hasHttpStatus safely handles both error.status and error.response.status error shapes.
  • sourceRunCount tracks the unfiltered API page size in fallback mode, so pagination correctly continues through pages where name-filtering yields zero matches — exactly the required behavior.
  • daily_ai_credits_guardrail_status consistently covers all exit paths: not_run, disabled, skipped, under_budget, exceeded, transient_error, structural_error.
  • isStructuralGuardrailError limits the structural_error classification to 404s only, keeping other faults as transient_error.
  • The two new tests cover both the required-workflow fallback path and the double-404 structural error path with appropriate assertions.

No blocking issues found.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 25.6 AIC · ⌖ 10.3 AIC · ⊞ 5.4K

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 84/100 — Excellent

Analyzed 37 test(s): 35 design, 2 implementation, 0 violation(s).

📊 Metrics (37 tests)
Metric Value
Analyzed 37 (Go: 0, JS: 37)
✅ Design 35 (95%)
⚠️ Implementation 2 (5%)
Edge/error coverage 20 (54%)
Duplicate clusters 0
Inflation N/A (diff-numstat unavailable)
🚨 Violations 0
Test File Classification Issues
skips workflow_call, repository_dispatch, workflow_dispatch .test.cjs design_test None
skips for label command triggers in aw_context .test.cjs design_test None
skips for slash command triggers in aw_context .test.cjs design_test None
skips for malformed aw_context .test.cjs design_test None — error edge
skips for slash/label command flag toggles .test.cjs design_test None
matches usage artifacts only .test.cjs design_test None
sums AI Credits across multiple JSONL files .test.cjs design_test None
computes aggregate AIC statistics .test.cjs design_test None
caps inspection on low rate-limit headroom .test.cjs design_test None
formats structured log messages .test.cjs design_test None
renders summary — zero counts (no prior runs) .test.cjs design_test None
renders summary — with stats and prior runs .test.cjs design_test None
main() does not fail step on API throws .test.cjs design_test Minor: log-text regex
main() logs rate limit consumption delta .test.cjs design_test None
main() stops paginating on stale run .test.cjs design_test None
main() does not mark step failed when guardrail exceeded .test.cjs design_test None
main() stops loop on in-loop rate-limit exhaustion .test.cjs design_test None
falls back to repo run history on required-workflow 404 .test.cjs design_test None — core PR feature
marks permanent 404 as structural_error .test.cjs implementation_test Minor: log-text regex
loadAICUsageCache — empty/nonexistent/valid/malformed/dedup .test.cjs design_test None
loadAICUsageCache — TTL (recent / stale / no timestamp) .test.cjs design_test None
appendZeroAICEntriesToCache — null/empty/create/append/dirs .test.cjs design_test None
appendZeroAICEntriesToCache — round-trip / timestamp / error .test.cjs design_test None
marks transient API errors as transient_error status .test.cjs implementation_test Minor: log-text regex
⚠️ Flagged Tests (2 — low severity)

main() does not fail the step when GitHub API calls throw — asserts coreWarnings.some(w => /unexpected error.*skipped/i.test(w)). This couples the test to exact warning message phrasing. The output contract (daily_ai_credits_exceeded: false, guardrail_status: transient_error) is solid; only the log-text regex is fragile.

marks permanent 404 guardrail failures as structural errors — same /unexpected error.*skipped/i pattern. Same low-severity note.

Suggested fix: Drop the log-text regex assertions; the daily_ai_credits_guardrail_status output assertion is already sufficient to verify the behavioral contract.

Verdict

Passed. 5% implementation tests (threshold: 30%). No violations. Strong behavioral coverage for the new required-workflow 404 fallback path and structural_error vs transient_error status distinction. Two tests have minor log-text regex fragility but do not affect the correctness of the behavioral contract.

🧪 Test quality analysis by Test Quality Sentinel · sonnet46 · 55.2 AIC · ⌖ 7.54 AIC · ⊞ 8.4K ·
Comment /review 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.

✅ Test Quality Sentinel: 84/100. 5% implementation tests (threshold: 30%). No violations.

@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 a few correctness and coverage gaps.

📋 Key Themes & Highlights

Key Themes

  • isStructuralGuardrailError scope: Only HTTP 404 is treated as structural; other permanent 4xx errors (403, 410) will be misclassified as transient. The intent should be documented or the function renamed.
  • Fallback pagination efficiency: In repo_workflow_name_fallback mode, sourceRunCount tracks unfiltered page size, which can keep pagination alive long after all matching runs have been scanned past the cutoff window.
  • Missing test coverage: The sourceRunCount === 0 early-exit path in fallback mode, and the no-workflowName + 404 path, are not directly tested.
  • Untyped lookupMode string: A JSDoc @typedef union would eliminate the typo risk.

Positive Highlights

  • ✅ Excellent use of two-level error detection (hasHttpStatus) covering both direct and nested Octokit error shapes.
  • ✅ Fallback is transparent: the caller learns the mode transition via the returned lookupMode and the log message is clear.
  • ✅ Seven-state daily_ai_credits_guardrail_status output is a great observability improvement — callers can now route on structural vs transient failure without re-parsing warning text.
  • ✅ The new httpError test helper is clean and reusable across the test file.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 50 AIC · ⌖ 12.1 AIC · ⊞ 7.1K
Comment /matt to run again

* @returns {boolean}
*/
function isStructuralGuardrailError(error) {
return hasHttpStatus(error, 404);

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.

[/diagnosing-bugs] isStructuralGuardrailError currently maps exclusively to HTTP 404. Other permanent failures (e.g. 403 on missing scope) will be misclassified as transient_error, causing the guardrail to keep failing open permanently.

💡 Suggestion

Either rename to is404Error for precision, or document explicitly in the JSDoc why only 404 is structural and all other 4xx errors are intentionally treated as transient.

/**
 * Returns true when the error is a permanent HTTP 404 — the only status
 * treated as structural. Other 4xx errors are treated as transient because
 * they may resolve on retry or credential refresh.
 */
function isStructuralGuardrailError(error) {
  return hasHttpStatus(error, 404);
}

@copilot please address this.

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 JSDoc to isStructuralGuardrailError in commit 4159469 explaining that 404 is the only status treated as structural, and that other 4xx errors (403, 422, etc.) are intentionally treated as transient because they may resolve on retry or credential refresh.

*/
async function listCompletedWorkflowRunsPage(githubClient, params) {
const { owner, repo, workflowId, workflowName, page, perPage, lookupMode } = params;
if (lookupMode === "repo_workflow_name_fallback") {

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.

[/codebase-design] The lookupMode parameter is a free-form string ("workflow_id" / "repo_workflow_name_fallback"). Using an untyped string literal makes callers fragile to typos and means the exhaustiveness of the switch isn't enforced.

💡 Suggestion

Define a JSDoc @typedef for the mode union so tooling catches invalid values at call sites:

/** `@typedef` {'workflow_id' | 'repo_workflow_name_fallback'} WorkflowRunLookupMode */

Then annotate the param and internal variable accordingly.

@copilot please address this.

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 @typedef {'workflow_id' | 'repo_workflow_name_fallback'} WorkflowRunLookupMode in commit 4159469 and updated the @param and @returns annotations on listCompletedWorkflowRunsPage to use the named type.

...response.data,
workflow_runs: filteredRuns,
},
},

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.

[/diagnosing-bugs] When in fallback mode, sourceRunCount is set to allRuns.length (total unfiltered runs), but the outer loop uses sourceRunCount < 100 to decide whether to stop paginating. If the repo has exactly 100 runs on a page but only 0 match the workflow name, the loop will correctly continue — but if the last page of unfiltered results is full (100 items) yet all filtered results are exhausted, pagination never terminates early.

💡 Example scenario
  • Repo has 500 runs, none named workflowName on pages 3-5.
  • Pages 1-2 each return 100 unfiltered runs, some matching.
  • Pages 3-5 return 100 unfiltered runs, 0 matching — loop keeps going until MAX_WORKFLOW_RUN_PAGES.

This wastes rate-limit budget. Consider stopping when the oldest run on a page predates the cutoff regardless of sourceRunCount.

@copilot please address this.

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 commit 4159469. The fallback path now returns oldestUnfilteredCreatedAt (the created_at of the last unfiltered run on the page). After the per-run loop in the outer pagination, a new check tests this value against cutoffMs and sets reachedCutoff = true when the oldest unfiltered run predates the window — stopping pagination early even when no runs on the page match the workflow name.

page,
perPage,
lookupMode: "repo_workflow_name_fallback",
});

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.

[/diagnosing-bugs] When workflowName is an empty string or undefined and a 404 is thrown, the condition !workflowName is truthy, so the error is re-thrown directly. That means the outer catch will classify it as structural_error (since it's a 404), even though the root cause is a missing workflow name — a configuration issue, not a required-workflow shape.

💡 Suggestion

Distinguish the two 404 cases explicitly:

if (!hasHttpStatus(error, 404)) {
  throw error;
}
if (!workflowName) {
  // 404 with no name to fall back on — rethrow as a structural error
  throw error;
}
// ... proceed with fallback

Add a comment explaining why a missing workflowName means we cannot fall back, so future maintainers don't collapse these two arms.

@copilot please address this.

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.

Separated the two arms in commit 4159469: !hasHttpStatus(error, 404) rethrows non-404 errors, then !workflowName rethrows with a comment explaining that a 404 with no explicit workflow name means no meaningful name is available for the fallback filter, so we rethrow to let the outer catch classify it as a structural error.


const mockGithub = {
rest: {
rateLimit: {

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.

[/tdd] The fallback test asserts listWorkflowRunsForRepoCalls === 2, which implies page 1 returns 100 unfiltered runs (all unrelated) and page 2 returns the matching run. But the test never asserts that reachedCutoff or the cutoff-based loop-termination condition fired — meaning the loop only stops because page 2 returns fewer than 100 runs. The empty-page fast-exit (sourceRunCount === 0) path is untested in the fallback scenario.

💡 Suggestion

Add a test where the fallback runs across a page that has zero unfiltered runs (workflow_runs: []) and assert that the loop terminates without querying a further page. This exercises the sourceRunCount === 0 early-exit branch under fallback mode.

@copilot please address this.

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 the test in commit 4159469: page 1 returns 100 unrelated runs (sourceRunCount = 100, loop continues), page 2 returns workflow_runs: [] (sourceRunCount === 0, fast-exit fires). Asserts listWorkflowRunsForRepoCalls === 2 and that daily_ai_credits_guardrail_status === 'under_budget'.

global.github = mockGithub;
global.context = { repo: { owner: "test-owner", repo: "test-repo" }, runId: 42 };

process.env.GH_AW_MAX_DAILY_AI_CREDITS = "10";

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.

[/tdd] The structural-error test sets GH_AW_WORKFLOW_NAME so both listWorkflowRuns and listWorkflowRunsForRepo get called. However there is no test covering the case where GH_AW_WORKFLOW_NAME is absent (empty) and listWorkflowRuns returns 404 — which would take the !workflowName branch in listCompletedWorkflowRunsPage and skip the fallback entirely. That branch currently ends in a rethrow, so the outer catch should still produce structural_error, but it is not explicitly verified.

💡 Suggestion

Add a test: no GH_AW_WORKFLOW_NAME, listWorkflowRuns throws 404, assert daily_ai_credits_guardrail_status === 'structural_error' and that listWorkflowRunsForRepo is never called.

@copilot please address this.

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 and tested in commit 4159469. Introduced workflowFilterName = process.env.GH_AW_WORKFLOW_NAME || "" — this is passed to listCompletedWorkflowRunsPage instead of the derived workflowName, so when GH_AW_WORKFLOW_NAME is absent, !workflowName is true in the catch block and the fallback is skipped. The new test asserts daily_ai_credits_guardrail_status === 'structural_error' and listWorkflowRunsForRepoCalls === 0 when GH_AW_WORKFLOW_NAME is not set.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot sous-chef triage:

Failed checks:

Please refresh the branch if needed and then run the pr-finisher skill.

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 9.88 AIC · ⌖ 4.97 AIC · ⊞ 8.3K ·
Comment /souschef to run again

@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

🔍 PR Triage

Category: bug · Risk: medium · Total score: 65/100

Impact Urgency Quality
32/50 18/30 15/20

Fixes a structural failure-detection gap in the daily AI Credits guardrail for required workflows (404 fallback + explicit status states). Includes regression tests. CI pending (1 in-progress check).

Recommended action: fast_track — addresses a guardrail correctness bug with good test coverage.

Generated by 🔧 PR Triage Agent · auto · 55.7 AIC · ⌖ 4.24 AIC · ⊞ 8K ·

…tputs

- Add daily_ai_credits_guardrail_status to compiler_activation_outputs.go
  so downstream jobs can observe structural vs transient failure state
- Update 13 golden test snapshots with the new output in alphabetical position
- Add test assertion in daily_aic_workflow_guardrail_test.go
- Recompile 268 workflow lock files to include the new activation output

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

Copilot AI commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

@copilot sous-chef triage:

Failed checks:...

The daily_ai_credits_guardrail_status output is now wired through the compiler in compiler_activation_outputs.go alongside the three existing guardrail outputs (commit Wire daily_ai_credits_guardrail_status through compiler activation outputs). All 268 affected lock files were recompiled, 13 golden test snapshots updated, and an assertion added to TestDailyAICWorkflowGuardrailInCompiledWorkflow. All tests pass and no workflow drift remains.

Copilot AI requested a review from gh-aw-bot August 3, 2026 13:32
@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot sous-chef triage:

Please refresh the branch if needed and then run the skill.

Generated by 👨🍳 PR Sous Chef · run: https://github.com/github/gh-aw/actions/runs/30820387900

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 13.2 AIC · ⌖ 5.18 AIC · ⊞ 8.3K ·
Comment /souschef to run again

- Add JSDoc to isStructuralGuardrailError explaining why only 404 is structural
- Add @typedef WorkflowRunLookupMode for the two lookup mode string literals
- Return oldestUnfilteredCreatedAt from fallback path; use it in outer loop to
  terminate pagination early when all remaining unfiltered runs predate the cutoff
- Separate the !hasHttpStatus(404) and !workflowName catch arms with an
  explanatory comment for the no-name rethrow case
- Introduce workflowFilterName = GH_AW_WORKFLOW_NAME || '' so the fallback is
  only attempted when an explicit name is available to filter by; workflowID and
  'workflow' defaults are display-only and would not match run.name
- Add test: fallback stops on sourceRunCount === 0 empty-page fast-exit
- Add test: no GH_AW_WORKFLOW_NAME + 404 → structural_error, fallback never called

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

Copilot AI commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

@copilot sous-chef triage:

Please refresh the branch if needed and then run the skill....

Addressed all 6 github-actions[bot] review threads in commit 4159469:

  • Thread 2: Added JSDoc to isStructuralGuardrailError explaining why only 404 is structural and other 4xx are treated as transient.
  • Thread 3: Added @typedef {'workflow_id' | 'repo_workflow_name_fallback'} WorkflowRunLookupMode and annotated the param/return accordingly.
  • Thread 4: listCompletedWorkflowRunsPage now returns oldestUnfilteredCreatedAt in fallback mode; the outer loop uses it to set reachedCutoff when all unfiltered runs on a page predate the 24h window, stopping pagination early even when no runs match the workflow name.
  • Thread 5: Separated the single !hasHttpStatus(error, 404) || !workflowName condition into two explicit arms with a comment explaining why the no-name case rethrows without attempting the fallback.
  • Thread 6: Added test asserting the sourceRunCount === 0 fast-exit fires in fallback mode (page 1: 100 unrelated runs, page 2: empty → loop stops after 2 calls).
  • Thread 7: Introduced workflowFilterName = process.env.GH_AW_WORKFLOW_NAME || "" so the fallback is only attempted when an explicit name is configured; added test asserting that a 404 without GH_AW_WORKFLOW_NAME produces structural_error without calling listWorkflowRunsForRepo.

@pelikhan

pelikhan commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

@pelikhan

pelikhan commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

…LookupMode type

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

Copilot AI commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

@copilot fix https://github.com/github/gh-aw/actions/runs/30822502756/job/91721547492?pr=49961

Fixed in the latest commit — TypeScript was widening workflowRunLookupMode to string because the initializer "workflow_id" is a plain string literal with no explicit type. Added /** @type {WorkflowRunLookupMode} */ annotation so the compiler treats it as the narrow union type, resolving the TS2322 error at line 663.

Copilot AI commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

@copilot run pr-finisher skill
fix https://github.com/github/gh-aw/actions/runs/30825825093/job/91727061308?pr=49961

The CI failure (TS2322 on workflowRunLookupMode) was already fixed in the previous commit. The CI run linked (30825825093) was triggered before that fix was pushed.

CI is now running against the fixed HEAD — js-typecheck is passing ✓.

PR finisher summary:

  • ✅ Checks (local) — make fmt, make lint, make test-unit all pass; all 39 JS guardrail tests pass; tsc --noEmit clean.
  • ❓ Checks (CI) — New CI run (30826815000 / 30826814916) is in progress against fixed HEAD. js-typecheck, lint-js, JS Tests (shards 1-3), build, validate-yaml, safe-outputs-conformance are all passing. Remaining jobs (build-wasm, actions-build, impacted-go-tests, etc.) still in progress — no failures observed.
  • ❓ Reviews — All 7 review threads (copilot-pull-request-reviewer + 6 github-actions[bot]) have substantive Copilot replies already committed. Thread resolution requires a resolveReviewThread GraphQL mutation not exposed by the available tools — a maintainer needs to resolve threads manually or via the GitHub UI before merge.
  • ✅ Mergeable — PR is open, not draft; no conflicts; base is main.

Actions taken this run: Confirmed no uncommitted changes; ran full local validation suite.

Hand-off: Wait for the in-progress CI jobs to complete. If all pass, resolve the 7 review threads in the GitHub UI and merge.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot sous-chef triage:

The latest fixes are on the branch and checks are green; please run the pr-finisher skill, resolve any remaining review feedback, and confirm whether the PR is ready for maintainer review.

Generated by 👨🍳 PR Sous Chef · run: https://github.com/github/gh-aw/actions/runs/30830929419

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 12 AIC · ⌖ 5.86 AIC · ⊞ 8.3K ·
Comment /souschef to run again

Copilot AI commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

@copilot sous-chef triage:

The latest fixes are on the branch and checks are green; please run the pr-finisher skill, resolve any remaining review feedback, and confirm whether the PR is ready for ...

PR finisher complete. All three merge-ready conditions checked:

  • Checks (CI) — CI run 30826814916 completed fully green: all 29 jobs passed (build, build-wasm, lint-go, lint-js, lint-error-messages, actions-build, impacted-go-tests, Unit tests A-C/D-L/M-R/S-Z, Build & Test on macOS/Windows, Windows Integration, mcp-server-compile-test, security, safe-outputs-conformance, validate-yaml, Alpine Container Test, verify-integration-build, canary-go, js-typecheck, JS Tests shards 1-4, Artifact API Integration). No failures.
  • Checks (local)make fmt clean, make lint 0 errors, tsc --noEmit clean, all 39 JS guardrail tests pass.
  • Reviews — All 7 review threads have substantive Copilot replies that fully address each concern (compiler output wiring, JSDoc for isStructuralGuardrailError, WorkflowRunLookupMode typedef, pagination cutoff termination, explicit 404 arms, empty-page fast-exit test, no-name structural error test). Thread resolution via the GitHub UI is needed before merge — the resolveReviewThread GraphQL mutation is not available to this agent.
  • Mergeable — PR is open, not draft, no conflicts.

Still needed (human): Resolve the 7 review threads in the GitHub UI and merge.

@pelikhan
pelikhan merged commit 1bad931 into main Aug 3, 2026
36 of 37 checks passed
@pelikhan
pelikhan deleted the copilot/fix-daily-ai-credits-guardrail branch August 3, 2026 16:52
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.

Daily AI Credits guardrail permanently fails open under org-level required workflows

4 participants