-
Notifications
You must be signed in to change notification settings - Fork 6
ci: advisory AI failure-investigation workflow (optional, needs ANTHROPIC_API_KEY) #1351
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
SharedQA
wants to merge
8
commits into
constructorfabric:main
Choose a base branch
from
SharedQA:claude/ai-investigate-failure
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+130
−0
Open
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
3be6005
ci: advisory AI failure-investigation workflow (optional, key-gated)
SharedQA 356b831
ci: skip AI investigation gracefully when ANTHROPIC_API_KEY is absent
SharedQA 2de5b27
Merge remote-tracking branch 'origin/main' into u-1351
SharedQA 8451483
Merge branch 'main' into claude/ai-investigate-failure
SharedQA d54a17b
ci(ai-investigate): scrub API key from subprocesses, SHA-pin the acti…
SharedQA 17f7d86
ci(ai-investigate): drop blanket Bash; scope to the exact git/gh comm…
SharedQA 767a3e1
Merge branch 'main' into claude/ai-investigate-failure
SharedQA bd5acd4
Merge branch 'main' into claude/ai-investigate-failure
SharedQA File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| # AI failure investigation — when a gate fails, the AI investigates with FULL | ||
| # context, because everything it needs is co-located in the repo: | ||
| # tests + PRD + DESIGN + ADRs + schemas + code, per component | ||
| # (docs/<unit>/specs/* and src/**/specs/*, registered in artifacts.toml). | ||
| # | ||
| # Trigger: any mandatory gate workflow finishing red on a PR branch. | ||
| # Output: an investigation comment on the PR — root-cause hypothesis, the | ||
| # spec section the failure violates (PRD/DESIGN traceability), suspect files, | ||
| # and a proposed fix or test. Advisory, never a gate: humans decide, AI digs. | ||
| # | ||
| # Optional: ANTHROPIC_API_KEY repo secret. When it is not set, the job skips | ||
| # its work and passes cleanly — this workflow is advisory and never a gate. | ||
|
|
||
| name: AI Investigate Failure | ||
|
|
||
| on: | ||
| workflow_run: | ||
| workflows: | ||
| - "Backend Lint & Test" | ||
| - "E2E — Bronze to API" | ||
| - "Security Gates" | ||
| - "Helm Validate" | ||
| - "Docs Gates" | ||
| - "Nightly Install Test" | ||
| - "Release Train" | ||
| types: [completed] | ||
|
|
||
| permissions: | ||
| contents: read | ||
| actions: read | ||
| pull-requests: write | ||
| issues: write | ||
|
|
||
| jobs: | ||
| investigate: | ||
| # Only for failures on SAME-REPO branches. A malicious fork cannot trigger | ||
| # this (which would run on the default branch with secret access + Bash and | ||
| # a head_sha checkout) — closes the workflow_run secret-exfiltration vector. | ||
| if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.head_repository.full_name == github.repository }} | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 15 | ||
| # Job-level env can read `secrets`; step-level `if` then gates on it. The | ||
| # ANTHROPIC_API_KEY secret is optional, so when it is absent the heavy steps | ||
| # are skipped and the workflow still passes (advisory, never a gate) instead | ||
| # of erroring out inside the action with no key. | ||
| env: | ||
| HAS_ANTHROPIC_KEY: ${{ secrets.ANTHROPIC_API_KEY != '' }} | ||
| # Defense-in-depth: best-effort scrub of ANTHROPIC_API_KEY from the | ||
| # subprocesses the action's Bash tool spawns, so a same-repo branch | ||
| # can't exfiltrate it via a planted command. The same-repo gate above | ||
| # already blocks forks; this hardens the same-repo path. | ||
| CLAUDE_CODE_SUBPROCESS_ENV_SCRUB: "1" | ||
| steps: | ||
| # nosemgrep: yaml.github-actions.security.workflow-run-target-code-checkout.workflow-run-target-code-checkout -- mitigated: job gated on head_repository == this repo (same-repo only), persist-credentials:false, no secrets used | ||
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||
| with: | ||
| ref: ${{ github.event.workflow_run.head_sha }} | ||
| persist-credentials: false | ||
|
|
||
| - name: Note when skipped (no API key) | ||
| if: env.HAS_ANTHROPIC_KEY != 'true' | ||
| run: echo "ANTHROPIC_API_KEY not configured — advisory AI investigation skipped; workflow passes." | ||
|
|
||
| - name: Collect failing job logs | ||
| if: env.HAS_ANTHROPIC_KEY == 'true' | ||
| # Untrusted workflow_run.* values are passed via env (shell quotes them), | ||
| # never interpolated into the script body — avoids template injection. | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| RUN_ID: ${{ github.event.workflow_run.id }} | ||
| WF_NAME: ${{ github.event.workflow_run.name }} | ||
| WF_BRANCH: ${{ github.event.workflow_run.head_branch }} | ||
| WF_SHA: ${{ github.event.workflow_run.head_sha }} | ||
| run: | | ||
| set -euo pipefail | ||
| mkdir -p /tmp/failure | ||
| # Best-effort: this is an advisory job, so log retrieval must never | ||
| # abort it (under pipefail a failing fallback pipeline would, which | ||
| # then skips the AI step via implicit success()). | ||
| if ! gh run view "$RUN_ID" --repo "$GITHUB_REPOSITORY" --log-failed \ | ||
| > /tmp/failure/failed-jobs.log 2>/dev/null; then | ||
| gh run view "$RUN_ID" --repo "$GITHUB_REPOSITORY" --log 2>/dev/null \ | ||
| | tail -800 > /tmp/failure/failed-jobs.log || true | ||
| fi | ||
| [ -s /tmp/failure/failed-jobs.log ] || echo "(no logs retrieved)" > /tmp/failure/failed-jobs.log | ||
| { | ||
| echo "workflow: $WF_NAME" | ||
| echo "branch: $WF_BRANCH" | ||
| echo "sha: $WF_SHA" | ||
| } > /tmp/failure/meta.txt | ||
|
|
||
| - name: AI investigation (full co-located context) | ||
| if: env.HAS_ANTHROPIC_KEY == 'true' | ||
| # SHA-pinned to v1 per the repo's hash-pin policy (CI supply-chain | ||
| # hardening — same as actions/checkout above); the trailing `# v1` | ||
| # documents the channel so Dependabot/Renovate can bump the pin. Runs | ||
| # only on workflow_run after a gate failed; advisory, no release artifact. | ||
| uses: anthropics/claude-code-action@30544b674398ee15c84819bd87caf8a87e8c7b55 # v1 | ||
| with: | ||
| anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} | ||
|
SharedQA marked this conversation as resolved.
|
||
| prompt: | | ||
| A mandatory CI gate failed. Investigate the root cause using the | ||
| full co-located context of this repository. | ||
|
|
||
| Failure metadata: /tmp/failure/meta.txt (workflow, branch, sha) | ||
| Failing job logs: /tmp/failure/failed-jobs.log | ||
|
|
||
| Method: | ||
| 1. Read the logs; identify the first real failure (not cascades). | ||
| 2. Locate the failing code/test/model. Read its CO-LOCATED specs: | ||
| the component's specs/PRD.md, specs/DESIGN.md, specs/ADR/*, | ||
| specs/schemas/* (see docs/DOCS_MAP.md and | ||
| cypilot/config/artifacts.toml for the code↔spec mapping). | ||
| 3. Determine: is the code violating the spec, is the test wrong, | ||
| or is the spec stale? Cite the exact PRD/DESIGN section. | ||
| 4. Identify suspect files/commits (git log on the touched paths). | ||
|
|
||
| Then post ONE comment on the PR for the branch named in | ||
| /tmp/failure/meta.txt (use `gh pr comment`) containing: ① root-cause | ||
| hypothesis with confidence, ② the spec section it traces to, | ||
| ③ suspect files with line refs, ④ a concrete proposed fix or | ||
| failing-test reproduction, ⑤ what to check if the hypothesis is | ||
| wrong. Be brief and factual. If no open PR exists for the branch, | ||
| open an issue titled "CI failure investigation" instead. | ||
| # Public-repo hardening: NO blanket Bash. The agent gets read/analysis | ||
| # tools plus only the exact git/gh commands it needs to inspect history | ||
| # and post its findings — so a prompt-injection in the failing logs | ||
| # can't run an arbitrary command (e.g. curl out ANTHROPIC_API_KEY). | ||
| # Layered with CLAUDE_CODE_SUBPROCESS_ENV_SCRUB + the same-repo gate. | ||
| claude_args: "--allowedTools Read,Grep,Glob,Bash(git log:*),Bash(gh pr list:*),Bash(gh pr view:*),Bash(gh pr comment:*),Bash(gh issue create:*),Bash(gh issue list:*) --max-turns 30" | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.