Skip to content

Include GitHub API rate limits in unified agent sessions - #66047

Merged
pelikhan merged 2 commits into
mainfrom
copilot/update-agent-unified-session-processor
Oct 6, 2026
Merged

pelikhan merged 2 commits into
mainfrom
copilot/update-agent-unified-session-processor

Conversation

Copilot AI commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Unified agent sessions did not include available GitHub API rate-limit evidence or identify which credential consumed the quota. This change brings those observations into the session trace where the information is available.

  • Session evidence: Collect quota state, observation source, operation, and retry details from the existing rate-limit log. Prefer the original file over its usage-artifact copy to avoid duplicates.
  • Credential attribution: Label per-handler API calls as GitHub Actions token, PAT, app token, or unknown without recording token values or inferring a type from quota size.
  • Session contract: Extend the unified-session schema and specification to describe the new observation.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI requested a review from pelikhan October 6, 2026 06:22
@pelikhan
pelikhan marked this pull request as ready for review October 6, 2026 06:23
Copilot AI balanced review requested due to automatic review settings October 6, 2026 06:23
@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

✅ Ponytail Reviewer completed successfully!

Lean already. Ship.

Generated by Ponytail Reviewer for #66047

@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

✅ Test Quality Sentinel completed test quality analysis.

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

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

✅ Design Decision Gate 🏗️ completed the design decision gate check. See the comment below for the result and any generated ADR draft.

No ADR enforcement needed for PR #66047: has_implementation_label=false and default_business_additions=0 (<=100) across 9 changed files, with no custom .design-gate.yml. Neither Condition A nor Condition B is met.

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer is reviewing this pull request using Matt Pocock's engineering skills...

@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

✅ PR Code Quality Reviewer completed the code quality review.

Attempting recovery after write command approval denial while preparing PR #66047 review output.

🔎 Code quality review by PR Code Quality Reviewer

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Credential attribution can be incorrect and does not cover per-handler GraphQL calls.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Adds GitHub API rate-limit observations and credential attribution to unified agent sessions.

Changes:

  • Collects and normalizes rate-limit JSONL events.
  • Classifies credentials for per-handler REST clients.
  • Extends tests, types, schema, and specification.
File Description
docs/​src/​content/​docs/​specs/​unified-agent-session-specification.md Documents rate-limit events.
docs/​public/​schemas/​unified-session.schema.json Defines the new payload schema.
actions/​setup/​js/​unified_session.test.cjs Tests collection and fallback behavior.
actions/​setup/​js/​unified_session.cjs Adds the rate-limit source.
actions/​setup/​js/​unified_session_payload.cjs Normalizes allowed fields.
actions/​setup/​js/​types/​unified_session.d.ts Adds TypeScript contracts.
actions/​setup/​js/​setup_globals.test.cjs Tests credential categories.
actions/​setup/​js/​setup_globals.cjs Classifies per-handler credentials.
actions/​setup/​js/​github_rate_limit_logger.cjs Records credential attribution.

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

Comment thread actions/setup/js/setup_globals.cjs Outdated
Comment on lines +40 to +42
if (process.env.GITHUB_TOKEN && token === process.env.GITHUB_TOKEN) return "github_actions";
if (token.startsWith("github_pat_") || token.startsWith("ghp_")) return "pat";
if (token.startsWith("ghs_") || token.startsWith("ghu_")) return "app";

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.

Removed the generic GITHUB_TOKEN comparison and token-prefix guessing. The compiler now passes canonical source provenance for the built-in client, and the explicitly PAT-backed handler auth path passes pat; other unproven tokens remain unknown. Fixed in 74f2487.

@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Comment Memory

Peek at saved memory (pr-code-quality-reviewer)
reviewed_at: 2026-10-06T06:27:13.613Z
review_event: REQUEST_CHANGES
top_themes:
  - incomplete credential attribution on rate-limit events
  - credentialSource sink should enforce the allowed category set
files_reviewed:
  - actions/setup/js/github_rate_limit_logger.cjs
  - actions/setup/js/setup_globals.cjs
  - actions/setup/js/setup_globals.test.cjs
  - actions/setup/js/types/unified_session.d.ts
  - actions/setup/js/unified_session.cjs
  - actions/setup/js/unified_session.test.cjs
  - actions/setup/js/unified_session_payload.cjs
  - docs/public/schemas/unified-session.schema.json
  - docs/src/content/docs/specs/unified-agent-session-specification.md
comment_count: 2

Note

This comment is managed by comment memory.

Expand the saved memory block to view or edit the persistent context for this thread.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 37.9 AIC · ⌖ 6.03 AIC · ⊞ 21.1K · ◷
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.

REQUEST_CHANGES

The credential-attribution change is incomplete: it only tags getOctokit(...) clients, while the default github client still emits unattributed rate-limit events.

Blocking themes
  • The built-in github client is still wrapped without a credential category, so the session trace will stay incomplete for the majority of github.rest.* traffic.
  • The new sink trusts arbitrary credentialSource strings instead of enforcing the promised small category set at the write boundary.

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 37.9 AIC · ⌖ 6.03 AIC · ⊞ 21.1K
Comment /review to run again

Comment thread actions/setup/js/setup_globals.cjs Outdated
applyGitHubApiVersion(requestOptions.headers, options.headers);
});
return client;
return createRateLimitAwareGithub(client, credentialSource(token));

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 only annotates getOctokit(...) clients; the default global.github client is still wrapped without a credential source, so most handler calls will keep producing unattributed rate-limit events and the new session field will miss the main quota consumer.

💡 Why this blocks merge

The stated goal is to identify which credential consumed GitHub API quota, but this change only passes credentialSource(token) on the custom-client path. The injected github client that actions/github-script gives us is still initialized as createRateLimitAwareGithub(githubModule) with no source, and that client is what the bulk of github.rest.* usage in this tree goes through.

A minimal fix is to tag the built-in client when globals are set up, for example by threading the known Actions token source into that wrapper too:

global.github = createRateLimitAwareGithub(githubModule, "github_actions");

If you need to avoid assuming the runtime token, derive the category once from the authenticated context and pass that canonical value into both wrapper sites so response_headers observations stay comparable.

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.

The Process Safe Outputs step now passes its compiler-derived credential source to setupGlobals, so rate-limit events from the default global.github client are attributed too. Fixed in 74f2487.

source: "response_headers",
operation,
};
if (credentialSource) entry.credentialSource = credentialSource;

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.

logRateLimitFromResponse now persists whatever truthy credentialSource string the caller hands it, so one bad call site will write raw auth context straight into the JSONL log.

💡 Why this needs hardening

This helper is exported and the new parameter is a free-form string. Right now the only in-tree caller passes a sanitized category, but the sink itself does not enforce that contract, so a future caller can accidentally log a token value, a header blob, or other high-cardinality data and the unified-session collector will happily preserve it.

Clamp the value at the write boundary instead of trusting every caller, e.g. only allow the canonical categories (github_actions, pat, app, unknown) and drop anything else:

const allowed = new Set(["github_actions", "pat", "app", "unknown"]);
if (allowed.has(credentialSource)) entry.credentialSource = credentialSource;

That keeps the observability field safe even if another caller gets this wrong later.

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.

The rate-limit logger now writes credentialSource only for the four canonical categories and omits invalid values; a test verifies raw token-like strings are not persisted. Fixed in 74f2487.

@github-actions github-actions Bot mentioned this pull request Oct 6, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Impeccable Skills Review

Change type: refactor_cleanup / backend observability (no UI) — applied general code-quality review (correctness, security, maintainability) since Impeccable's UI-focused modes (critique, audit, harden, distill, extract, clarify) do not apply to this backend JS/schema change.

Findings

No blocking or high-signal issues found. The change is well-scoped and consistent:

  • credentialSource() classification logic (setup_globals.cjs) correctly checks exact GITHUB_TOKEN equality before prefix matching, never persists/logs raw tokens, and defaults safely to "unknown".
  • logRateLimitFromResponse/createRateLimitAwareGithub thread the optional credentialSource through without altering existing behavior when omitted (step-level global.github remains unclassified, matching the "per-handler" scope described in the PR).
  • unified_session.cjs collector change follows the existing [candidates, component, phase, type] pattern; choose() already prefers the first existing candidate, satisfying the "prefer original over usage copy" requirement without new logic.
  • New github_api.rate_limit event type is consistently wired through .d.ts types, the JSON Schema (additionalProperties:false, matching field set), the payload field-alias map (snake_case/camelCase aliases for credential_source/delay_ms), and the specification doc.
  • Tests cover the credential classification matrix, malformed-line skipping, dedup across github_rate_limits.jsonl vs. its usage/ copy, and unknown-field stripping (authorization is correctly dropped).

Nothing actionable to request changes on.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · copilot · sonnet50 · 139.5 AIC · ⌖ 13.2 AIC · ⊞ 8.2K

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot address the following outstanding work in one pass:

  1. Update this branch with the latest main using make merge-main, resolving any conflicts and preserving the intended changes.
  2. Review (actions/setup/js/setup_globals.cjs:42): GITHUB_TOKEN is not a reliable marker for the Actions credential here. The Process Safe Outputs step does not export it for the default token path, so a fallback secrets.GITHUB_TOKEN (normally ghs_...) is classified as app; conversely, compiler_safe_outputs_steps.go:529-543 deliberately exports custom PAT/app credentials as GITHUB_TOKEN, causing those to be classified as github_actions. Pass explicit credential provenance from the compiler/caller (or a dedicated Actions-token marker) instead of comparing with this generic environment variable. - Include GitHub API rate limits in unified agent sessions #66047 (comment)
  3. Review (actions/setup/js/setup_globals.cjs:100): This only annotates getOctokit(...) clients; the default global.github client is still wrapped without a credential source, so most handler calls will keep producing unattributed rate-limit events and the new session field will miss the main quota consumer. - Include GitHub API rate limits in unified agent sessions #66047 (comment)
  4. Review (actions/setup/js/github_rate_limit_logger.cjs:114): logRateLimitFromResponse now persists whatever truthy credentialSource string the caller hands it, so one bad call site will write raw auth context straight into the JSONL log. - Include GitHub API rate limits in unified agent sessions #66047 (comment)
  5. Fix failing check agent (FAILURE): https://github.com/github/gh-aw/actions/runs/37423508218/job/112138448507.
  6. Fix failing check conclusion (FAILURE): https://github.com/github/gh-aw/actions/runs/37423508218/job/112143895523.

Push the necessary fixes, reply to each listed review thread and resolve it when addressed. Ignore feedback already answered or resolved. Use the pr-finisher skill and stop when only human review or CI remains; do not trigger CI.

Sous-chef head: 33789a5
Sous-chef work: 34f38971738f6a752a646bd7797a6c8d47fb096e4eb6f91e946a91255433c8c4 3d535ddbcf5eb8f652795b58c457660d2474c82cedec7f839fc58852a6af2188 51e2287c3d1ee41b7e13769862add61dcd292a623cf943abc5968c984e246bcf 702d489fbe257a777c3767505ebfe7da7593c09a3ffa71ed8a39984ff86299b7 d4068e3322287345d3893ea4cc551f00db2dbe29adceacf7d9ac4b5a5753dc47
Sous-chef state: fe2760a944c8d649596343f907edf5d16adc6e96153863a8af70254d87ff38f4

Generated by 👨‍🍳 PR Sous Chef · pi · haiku45 · 11.4 AIC · ⌖ 7.68 AIC · ⊞ 1K · ◷
Comment /souschef to run again

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Copilot AI requested a review from gh-aw-bot October 6, 2026 07:39
@pelikhan
pelikhan merged commit 54be7a5 into main Oct 6, 2026
2 checks passed
@pelikhan
pelikhan deleted the copilot/update-agent-unified-session-processor branch October 6, 2026 11:45
@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.91.2

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants