Skip to content

Harden Pi provider retries and failure diagnostics - #65562

Merged
pelikhan merged 6 commits into
mainfrom
copilot/diagnose-harden-pi-engine-failures
Oct 4, 2026
Merged

pelikhan merged 6 commits into
mainfrom
copilot/diagnose-harden-pi-engine-failures

Conversation

Copilot AI commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Pi provider failures, including rate limits, could end as generic infrastructure errors without actionable response details.

  • Retries: Enable up to two Pi SDK retries for transient provider errors, with a 1-second base delay and a 30-second delay cap.
  • Diagnostics: Include the provider HTTP status and bounded, sanitized response message in failure reports and logs.
retry: { enabled: true, maxRetries: 2, baseDelayMs: 1000, maxAgentDelayMs: 30000 }

Copilot AI and others added 3 commits October 4, 2026 13:26
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Diagnose and harden Pi engine provider request failures Harden Pi provider retries and failure diagnostics Oct 4, 2026
Copilot AI requested a review from pelikhan October 4, 2026 13:31
@pelikhan
pelikhan marked this pull request as ready for review October 4, 2026 13:32
Copilot AI balanced review requested due to automatic review settings October 4, 2026 13:32
@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

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

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

@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

✅ PR Code Quality Reviewer completed the code quality review.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

✅ Ponytail Reviewer completed successfully!

Lean already. Ship.

Generated by Ponytail Reviewer for #65562

@github-actions

github-actions Bot commented Oct 4, 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.

Warning

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

What happened

The threat detection engine failed to produce results.

Review the workflow run logs for details.

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Oct 4, 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

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

It rejects compiler-generated queue expressions, removes active command routes, and leaks secrets through agent_end snapshots.

Review effort: Balanced
Findings: 3 High severity

Open (3)
What changed in this PR

Hardens Pi provider execution with retries and sanitized failure diagnostics.

Changes:

  • Configures bounded Pi SDK retries.
  • Adds provider error extraction, redaction, reporting, and tests.
  • Regenerates workflow routing and adjusts concurrency schema validation.
File Description
pkg/​workflow/​schemas/​github-workflow.json Restricts concurrency queue values.
go.mod Promotes YAML v3 to a direct dependency.
actions/​setup/​js/​pi_runtime.cjs Adds default retry settings.
actions/​setup/​js/​pi_runtime.test.cjs Verifies retry configuration.
actions/​setup/​js/​pi_provider.cjs Reports sanitized provider failures.
actions/​setup/​js/​pi_provider.test.cjs Tests failure diagnostics and redaction.
actions/​setup/​js/​pi_provider_error.cjs Implements bounded error sanitization.
actions/​setup/​js/​pi_agent_core_driver.cjs Sanitizes streamed error events.
actions/​setup/​js/​pi_agent_core_driver.test.cjs Tests event redaction.
.github/​workflows/​agentic_commands.yml Regenerates command routing.
.changeset/​patch-harden-pi-provider-failures.md Documents the patch.

Comment thread .github/workflows/agentic_commands.yml Outdated
@@ -1,4 +1,4 @@
# gh-aw-commands: {"payload_version":"v1","schema_version":"v1","compiler_version":"dev","commands":["*","ace","approach-validator","archie","cloclo","craft","dependabot-burner","grumpy","matt","mergefest","nit","plan","poem-bot","ponytail","review","ruflo","scout","security-review","smoke-agent-all-merged","smoke-agent-all-none","smoke-agent-public-approved","smoke-agent-public-none","smoke-agent-scoped-approved","smoke-aider","smoke-call-workflow","smoke-checkout-pr-dispatch","smoke-claude","smoke-claude-on-copilot","smoke-codex","smoke-copilot","smoke-copilot-aoai-apikey","smoke-copilot-aoai-entra","smoke-copilot-arm","smoke-copilot-mai","smoke-copilot-sdk","smoke-copilot-small","smoke-create-cross-repo-pr","smoke-crush","smoke-cursor","smoke-deepseek-harness","smoke-drive","smoke-gemini","smoke-github-claude","smoke-goose","smoke-kiro","smoke-multi-pr","smoke-opencode","smoke-otel-backends","smoke-pi","smoke-project","smoke-pydantic","smoke-service-ports","smoke-temporary-id","smoke-test-tools","smoke-update-cross-repo-pr","souschef","squad-plan","summarize","tidy","unbloat","windows"],"workflows":["ace-editor","approach-validator","archie","cloclo","craft","dependabot-burner","design-decision-gate","dev","grumpy-reviewer","mattpocock-skills-reviewer","mergefest","necromancer","pdf-summary","plan","poem-bot","ponytail-reviewer","pr-code-quality-reviewer","pr-nitpick-reviewer","pr-sous-chef","ruflo-backed-task","scout","security-review","skillet","smoke-agent-all-merged","smoke-agent-all-none","smoke-agent-public-approved","smoke-agent-public-none","smoke-agent-scoped-approved","smoke-aider","smoke-call-workflow","smoke-checkout-pr-dispatch","smoke-claude","smoke-claude-on-copilot","smoke-codex","smoke-copilot","smoke-copilot-aoai-apikey","smoke-copilot-aoai-entra","smoke-copilot-arm","smoke-copilot-mai","smoke-copilot-sdk","smoke-copilot-small","smoke-create-cross-repo-pr","smoke-crush","smoke-cursor","smoke-deepseek-harness","smoke-drive","smoke-gemini","smoke-github-claude","smoke-goose","smoke-kiro","smoke-multi-pr","smoke-opencode","smoke-otel-backends","smoke-pi","smoke-project","smoke-pydantic","smoke-service-ports","smoke-temporary-id","smoke-test-tools","smoke-update-cross-repo-pr","squad-plan","test-quality-sentinel","tidy","unbloat-docs","windows"]}
# gh-aw-commands: {"payload_version":"v1","schema_version":"v1","compiler_version":"dev","commands":["*","ace","approach-validator","archie","cloclo","craft","dependabot-burner","grumpy","mergefest","nit","plan","poem-bot","ruflo","scout","security-review","smoke-claude-on-copilot","smoke-copilot","smoke-copilot-aoai-apikey","smoke-copilot-aoai-entra","smoke-copilot-mai","smoke-copilot-sdk","smoke-copilot-small","smoke-github-claude","smoke-otel-backends","smoke-service-ports","souschef","squad-plan","summarize","tidy","unbloat","windows"],"workflows":["ace-editor","approach-validator","archie","cloclo","craft","dependabot-burner","dev","grumpy-reviewer","mergefest","necromancer","pdf-summary","plan","poem-bot","pr-nitpick-reviewer","pr-sous-chef","ruflo-backed-task","scout","security-review","skillet","smoke-claude-on-copilot","smoke-copilot","smoke-copilot-aoai-apikey","smoke-copilot-aoai-entra","smoke-copilot-mai","smoke-copilot-sdk","smoke-copilot-small","smoke-github-claude","smoke-otel-backends","smoke-service-ports","squad-plan","tidy","unbloat-docs","windows"]}

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.

Restored the complete generated route table by restoring expression-capable queue validation and recompiling; /review, /ponytail, and /smoke-pi are present. All 320 workflows compile. Commit: 452c0a8.

Comment on lines +13 to +20
if (event.type !== "message_update") {
const sanitized = { ...event };
if (typeof event.errorMessage === "string") sanitized.errorMessage = sanitizeProviderErrorMessage(event.errorMessage);
if (typeof event.message?.errorMessage === "string") {
sanitized.message = { ...event.message, errorMessage: sanitizeProviderErrorMessage(event.message.errorMessage) };
}
return sanitized;
}

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.

Sanitized assistant errorMessage fields in event.messages[] and added an agent_end regression test. Commit: 452c0a8.

Comment thread pkg/workflow/schemas/github-workflow.json Outdated
@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-10-04T13:45:42Z
review_event: REQUEST_CHANGES
top_themes:
  - broken slash-command and workflow routing regeneration
  - shallow retry settings merge can defeat Pi retry rollout
  - schema regression for expression-valued concurrency.queue
files_reviewed:
  - .github/workflows/agentic_commands.yml
  - actions/setup/js/pi_agent_core_driver.cjs
  - actions/setup/js/pi_agent_core_driver.test.cjs
  - actions/setup/js/pi_provider.cjs
  - actions/setup/js/pi_provider.test.cjs
  - actions/setup/js/pi_provider_error.cjs
  - actions/setup/js/pi_runtime.cjs
  - actions/setup/js/pi_runtime.test.cjs
  - pkg/workflow/schemas/github-workflow.json
comment_count: 3

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
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 · 48.9 AIC · ⌖ 7.35 AIC · ⊞ 19.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.

Request changes

This PR mixes the Pi diagnostics work with unrelated routing and schema regressions that would break existing workflows and slash-command dispatch.

Blocking themes
  • agentic_commands.yml drops a large set of still-present commands and workflows from routing.
  • preparePiRuntime() adds retry defaults with a shallow merge, so existing retry config can nullify or partially erase the new behavior.
  • github-workflow.json stops accepting expression-valued concurrency.queue, but the repository already ships many workflows that rely on that syntax.

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 48.9 AIC · ⌖ 7.35 AIC · ⊞ 19.4K
Comment /review to run again

Comments that could not be inline-anchored

.github/workflows/agentic_commands.yml:147

This regeneration drops existing routes like /review, /matt, /ponytail, and multiple smoke workflows even though their workflow files are still in the repo, so merging this would silently break dispatch for commands that already exist.

<details><summary>💡 Why this blocks</summary>

The diff removes these entries from the generated command inventory and the slash-routing payload without deleting the corresponding workflow sources. That means the workflows still exist, but the router stop…

actions/setup/js/pi_runtime.cjs:101

This retry default is only shallow-merged, so any existing settings.json.retry object replaces it wholesale and can silently disable retries or drop the new delay caps.

<details><summary>💡 Why this blocks</summary>

preparePiRuntime() spreads installedSettings and then config.settings over the top-level object. If either source already contains retry, the entire default object you just added is overwritten instead of merged field by field. For example, an older install that only h…

pkg/workflow/schemas/github-workflow.json:46

Narrowing concurrency.queue to a literal enum breaks existing workflows that use ${{ ... }} expressions here, so schema validation will start rejecting workflows we already ship.

<details><summary>💡 Why this blocks</summary>

This repo already checks in many generated workflows with queue: ${{ github.event_name == &quot;pull_request&quot; &amp;&amp; &quot;single&quot; || &quot;max&quot; }} such as pr-code-quality-reviewer.lock.yml, design-decision-gate.lock.yml, and multiple smoke workflows. After this change, those val…

@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: the schema change in this PR regresses concurrency.queue expression support and fails existing tests on this branch.

📋 Key Themes & Highlights

Key Themes

  • Blocking regression: pkg/workflow/schemas/github-workflow.json drops the expressionSyntax alternative for concurrency.queue, breaking TestConcurrencyQueueSchemaValidation and two TestCommandConcurrencyCompilation subtests (verified locally — all three fail on this branch). This appears unrelated to the Pi provider hardening goal and should be reverted or fixed.
  • Test coverage gap: the new pi_provider_error.cjs redaction/parsing helpers are security-sensitive but only tested indirectly through pi_provider.test.cjs/pi_agent_core_driver.test.cjs; a dedicated unit test file would pin down the regex edge cases directly.

Positive Highlights

  • ✅ getProviderErrorDetails/sanitizeProviderErrorMessage are a clean, single-purpose extraction that keeps pi_provider.cjs readable.
  • ✅ Good defense-in-depth: both env-var-driven and pattern-based (Bearer, ghp_, sk-...) secret redaction, plus a length cap.
  • ✅ New tests in pi_provider.test.cjs and pi_agent_core_driver.test.cjs assert both that the useful diagnostic (status/message) is present and that the secret is absent — good regression-test shape per /tdd.
  • ✅ pi_runtime.cjs retry defaults (maxRetries: 2, capped backoff) are a reasonable, test-covered hardening default.

Unrelated to this PR's code: note that .github/workflows/agentic_commands.yml's diff appears to be a large routing-table regeneration (likely from gh aw compile/gh aw update), not reviewed in depth here.

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

}
]
},
"queue": {

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] This diff removes the expressionSyntax alternative from concurrency.queue, regressing support for ${{ ... }} expressions (e.g. queue: ${{ github.event_name == 'pull_request' && 'single' || 'max' }} used by command-triggered workflows). This is unrelated to the Pi provider hardening goal of this PR and breaks existing coverage.

💡 Verification & fix

Running the existing suite against this branch fails:

go test ./pkg/workflow/... -run 'TestConcurrencyQueueSchemaValidation|TestCommandConcurrencyCompilation'
--- FAIL: TestCommandConcurrencyCompilation/centralized_command_and_PR
--- FAIL: TestCommandConcurrencyCompilation/label_command_and_PR
--- FAIL: TestConcurrencyQueueSchemaValidation
    .../concurrency: 'oneOf' failed, none matched
    - at '/concurrency/queue': value must be one of 'single', 'max'

pkg/workflow/concurrency_command_test.go expects queue: ${{ github.event_name == 'pull_request' && 'single' || 'max' }} to validate successfully (see TestCommandConcurrencyCompilation/centralized_command_and_PR and TestConcurrencyQueueSchemaValidation), which this schema no longer allows since the oneOf + expressionSyntax branch was dropped in favor of a plain string enum.

This looks like an accidental revert/leftover from an unrelated change swept into this PR — restore the oneOf with expressionSyntax so command-triggered workflows that compute queue dynamically keep validating.

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

Restored the enum-or-expression oneOf for concurrency.queue; the targeted queue-schema and command-concurrency Go tests pass. Commit: 452c0a8.

message = value;
} else {
try {
message = JSON.stringify(value);

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] sanitizeProviderErrorMessage and getProviderErrorDetails are new, security-sensitive functions (credential redaction) but have no dedicated unit test file — coverage currently comes only indirectly via pi_provider.test.cjs and pi_agent_core_driver.test.cjs.

💡 Suggested tests

Add pi_provider_error.test.cjs covering edge cases directly, e.g.:

it("redacts Bearer tokens and GH tokens regardless of env vars", () => {
  expect(sanitizeProviderErrorMessage("Authorization: Bearer abc123")).not.toContain("abc123");
  expect(sanitizeProviderErrorMessage("ghp_abcdefghijklmnopqrstuvwxyz0123456789")).toContain("[REDACTED]");
});

it("truncates very long messages", () => {
  const long = "x".repeat(2000);
  expect(sanitizeProviderErrorMessage(long).length).toBeLessThanOrEqual(1001);
});

it("parses status prefix from getProviderErrorDetails when no responseStatus given", () => {
  expect(getProviderErrorDetails("429: rate limited", undefined)).toEqual({ status: 429, message: "rate limited" });
});

This makes regressions in the redaction regexes (e.g. the control-char/secret patterns) fail fast and close to the change, per /tdd.

@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 dedicated tests for provider-error redaction, control-character removal, length bounding, and status parsing in pi_provider_error.test.cjs. The impacted setup JS suite passes. Commit: 452c0a8.

@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 Review (harden mode) — verified existing findings

Ran the Impeccable harden + audit checks (bug-fix/reliability change). Three blocking issues were already flagged by a prior review pass on this PR; I independently reproduced and confirmed all three are real:

  1. pkg/workflow/schemas/github-workflow.json (concurrency.queue) — dropping the expressionSyntax oneOf branch breaks existing behavior. Confirmed by running:

    go test ./pkg/workflow/... -run 'TestConcurrencyQueueSchemaValidation|TestCommandConcurrencyCompilation'
    

    Both fail: TestConcurrencyQueueSchemaValidation and TestCommandConcurrencyCompilation/centralized_command_and_PR + /label_command_and_PR error with jsonschema validation failed ... value must be one of 'single', 'max' because the compiler still emits ${{ github.event_name == 'pull_request' && 'single' || 'max' }} for mixed command/PR concurrency groups. This is a genuine regression, not a false positive.

  2. .github/workflows/agentic_commands.yml routing table — the regenerated routing table drops /review, /matt, /ponytail, /smoke-pi, /smoke-claude, /smoke-codex, and many other smoke-* commands and workflows, even though their source workflow files are untouched by this PR. This file shouldn't be hand-regenerated as part of an unrelated Pi-retry change — looks like it was compiled against a stale/filtered workflow set.

  3. pi_agent_core_driver.cjs: jsonEvent — the sanitizer only redacts event.errorMessage and event.message.errorMessage, but agent_end events carry errors in event.messages[] (plural, array) per the existing fixtures (fixtures/pi_ci_stream.cjs:58,84, pi_session.test.cjs). Any assistant error captured via that path is emitted to the session log/stdout unsanitized, which can leak provider secrets — directly undermining the stated goal of this PR ("sanitized response message in failure reports and logs").

No new issues beyond these found on review. Given issue (3) is a secret-leak regression in the very code this PR adds, and (1)/(2) are confirmed test failures / unrelated-file regressions, this PR should not merge until addressed.

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

@pelikhan

pelikhan commented Oct 4, 2026

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

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

Copilot AI commented Oct 4, 2026

Copy link
Copy Markdown
Contributor Author

@copilot run pr-finisher skill

Finisher pass completed; pushed 452c0a8. Local validation passed and I replied to the in-scope review comments. Review threads could not be resolved with the available tools. CI is stale after this push and must be re-triggered by a maintainer; the PR remains blocked pending review.

Comment on lines +414 to +417
const providerFailureDetails = lastProviderFailure
? ` Last provider failure: ${typeof lastProviderFailure.status === "number" ? `HTTP ${lastProviderFailure.status}; ` : ""}message=${JSON.stringify(lastProviderFailure.message)}.`
: "";
emitInfrastructureIncompleteIfNoSafeOutputs(`All ${providerRequestCount} Pi provider requests failed before safe outputs were emitted.${providerFailureDetails}`, log);
@pelikhan
pelikhan merged commit 025d824 into main Oct 4, 2026
2 checks passed
@pelikhan
pelikhan deleted the copilot/diagnose-harden-pi-engine-failures branch October 4, 2026 17:00
@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.91.0

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.

[AW Top 10] 10 Diagnose and harden Pi engine provider request failures

4 participants