fix(workflows): restore CI Claude permissions broken by claude-code-action bump (pipeline generated nothing since July 5)#9651
Merged
Conversation
…their permissions
Since the July 5 claude-code-action bump (Claude Code CLI 2.1.170 ->
2.1.211), the CLI ignores permissions.allow entries from
.claude/settings.json when the workspace is not trusted - and a CI
checkout never is. Every pipeline Claude step has run with zero write
permissions since then: 18-20 tool denials per run, no implementation
files, no plots, nothing generated repo-wide since July 1.
Passing --settings .claude/settings.json in claude_args is honored by
the trust gate as an explicit opt-in (verified locally on CLI 2.1.218:
denial reproduced without the flag, file written with it). Apply it to
all 12 claude-code-action steps across the 7 workflows.
Also fix a backtick fragment in the metadata step's Python heredoc
comment that bash command-substituted on every run
("--model: command not found").
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
MarkusNeusinger
added a commit
that referenced
this pull request
Jul 23, 2026
Root cause of the pipeline breakage is found and fixed in PR #9651 — no further validation runs on this branch are needed or even possible: the action's OAuth token exchange 401s any run whose workflow file differs from the default branch ('Workflow validation failed. The workflow file must exist and have identical content to the version on the repository's default branch.'). That 401 is also why the earlier July-1-pin validation run produced an empty result: Claude never started, so it neither confirmed nor refuted the action-version hypothesis. The actual mechanism (confirmed by local repro): CLI 2.1.171+ ignores permissions.allow from .claude/settings.json in untrusted workspaces, and CI checkouts are never trusted; explicit --settings in claude_args is honored and fixes it. impl-generate.yml is now byte-identical to main again, leaving this PR with only its cron-offset + watchdog-liveness content. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Restores write-capable Claude Code execution in CI after a claude-code-action/CLI bump caused .claude/settings.json permissions.allow entries to be ignored in untrusted workspaces, preventing all pipeline-generated files from being created.
Changes:
- Adds an explicit
--settings ${{ github.workspace }}/.claude/settings.jsonto allanthropics/claude-code-actionsteps so the allowlist is honored in CI. - Fixes a bash command-substitution issue in
impl-generatewhere backticks inside the Python-c "..."string were executed by the shell. - Documents both fixes in
CHANGELOG.mdunder Fixed.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
CHANGELOG.md |
Adds an Unreleased “Fixed” entry documenting the restored Claude pipeline permissions and the metadata-step backtick substitution fix. |
.github/workflows/util-claude.yml |
Passes --settings to Claude Code runs to restore allowlisted tool permissions. |
.github/workflows/spec-create.yml |
Passes --settings to both spec-create Claude steps to restore write/edit capabilities. |
.github/workflows/report-validate.yml |
Passes --settings to the Claude validation step to restore allowlisted permissions. |
.github/workflows/impl-review.yml |
Passes --settings to the AI quality review step to ensure consistent permissions. |
.github/workflows/impl-repair.yml |
Passes --settings to repair + retry Claude steps so repairs can actually write changes. |
.github/workflows/impl-generate.yml |
Passes --settings to generate + retry steps; removes backticks in the Python -c block comment to prevent shell command substitution. |
.github/workflows/daily-regen.yml |
Passes --settings to spec-polish and similarity-audit Claude steps so they can write outputs when needed. |
6 tasks
… 2.1.211 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Problem
No implementation has been generated repo-wide since July 1. Every
impl-generaterun since the July 5 Dependabot bump ofanthropics/claude-code-action(#9513, again #9643) shows the same signature: the Claude step reportsis_error: falseafter30 turns ($1.5-2.0 spent), butpermission_denials_count: 18-20and neither the implementation file norplot-light.png/plot-dark.pngexist afterwards. Thedaily-regenpreflight steps (spec polish, similarity audit) show the same denials (1 and 7 per run). Because failures never advance the metadataupdatedtimestamp, daily-regen re-picks the same oldest spec (heatmap-calendar) every tick and burns 15 failing runs per cycle.Root cause
The action bump carried a Claude Code CLI bump: 2.1.170 → 2.1.211. Newer CLIs ignore
permissions.allowentries from.claude/settings.jsonwhen the workspace has not been trusted (interactive trust dialog /hasTrustDialogAcceptedin~/.claude.json) — and a fresh CI runner is never trusted. So the repo's allowlist (Write,Edit,Bash, …) was silently dropped and headless mode denied every write-capable tool call. Claude "finished" politely after being denied ~19 times, the action reported success, and the workflow failed later at the metadata/image steps.Reproduced locally on CLI 2.1.218 with the repo's exact allowlist in a scratch project:
→
Writedenied, no file created (turns=2, exactly the CI pattern).Fix
Pass the repo's settings file explicitly — the trust gate honors an explicit
--settingsflag as opt-in. Verified locally: same prompt, same allowlist, with--settings .claude/settings.jsonthe file is written with 0 denials.Applied to all 12
claude-code-actionsteps across 7 workflows (impl-generate×2,impl-repair×2,spec-create×2,daily-regen×2,util-claude×2,impl-review,report-validate):Also fixed while in the file: a backtick fragment in the metadata step's Python-heredoc comment was command-substituted by bash on every run (
--model: command not foundin all run logs) — now single-quoted.Why there is no green branch-CI proof
Branch-side validation of any change to these workflows is structurally impossible: the action's OAuth token exchange rejects runs whose workflow file differs from the default branch (
401 Workflow validation failed. The workflow file must exist and have identical content to the version on the repository's default branch.). This was verified with a dispatch of a pinned test variant — Claude never even started. The local reproduction above is the validation.Post-merge confirmation run
After merge, dispatch a single real generation and confirm it produces files:
Expected:
permission_denials_count: 0, implementation + both PNGs committed, run green through metadata/image steps.🤖 Generated with Claude Code
Upstream context (source/changelog audit of the action + CLI)
11ba6048= action v1.0.142 (bundled CLI 2.1.170, worked) → Dependabot deps(actions): bump the actions group across 1 directory with 3 updates #9513 (July 5) = v1.0.159 (CLI 2.1.195, first broken) → deps(actions): Bump the actions group across 3 directories with 6 updates #9643 (July 20) = v1.0.175 (CLI 2.1.211, still broken). The action's agent-mode permission plumbing is identical across all three refs — the only variable is the bundled CLI..claude/settings.json(MCP), and 2.1.207 documents that only user,--settings, and managed settings remain trusted sources. That is why the explicit--settingsflag is the upstream-blessed mechanism, not a workaround.--settingsinclaude_argspermanently.--permission-mode bypassPermissions(works, but drops the allowlist semantics and any futuredenyrules) and pinning the action back to v1.0.142 (forgoes the v1.0.175 CI-correctness fixes:is_error→ real failure, PR-trigger iterator hang, Bun tsconfig crash).