feat(workflows): raise Claude max-turns to 50 and split models by job difficulty - #17
Merged
Merged
Conversation
… difficulty Raise the default turn budget on every Claude-powered workflow from 5-30 to 50 so large PRs no longer flake with error_max_turns, and replace the flat haiku model with a difficulty-based split, overridable per caller via a new 'model' input on each analysis workflow: - opus: security-owasp, quality-async, a11y-wcag, claude-review, claude (@claude mentions), auto-fix - sonnet: security-secrets, security-deps, quality-typescript, quality-code-smell, a11y-aria, auto-resolve-conflicts Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vuuw6bCHCoYyhT7Q6jXhRj
This was referenced Jul 2, 2026
Merged
laurigates
added a commit
that referenced
this pull request
Jul 2, 2026
…deprecated direct_prompt (#18) > **Stacked on #17** — do not merge before #17. When #17 merges, retarget this PR to `main` first (it will auto-close otherwise). ## What Two latent bugs found while auditing against the [claude-code-action docs](https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md): ### 1. Analysis workflow outputs were always empty All eight analysis workflows declared job outputs like `issues-found: ${{ steps.scan.outputs.total }}`, but the action only exposes `execution_file`, `branch_name`, `github_token`, `structured_output`, and `session_id`. Asking Claude to print `TOTAL_ISSUES: n` in a PR comment never produced a step output, so: - every declared workflow output was empty - **`fail-on-critical` (OWASP) and `fail-on-high` (deps) could never fire** — the gate compared against an empty string Fix: pass `--json-schema` in `claude_args` (the action's supported structured-output mechanism) and read counts via `fromJSON(steps.<id>.outputs.structured_output || '{}').<field>`. The `|| '{}'` guard keeps output evaluation safe when the analysis step is skipped (no matching changed files). Prompts now instruct Claude to fill the structured fields instead of printing count markers. ### 2. `reusable-auto-fix` used the removed-soon `direct_prompt` input `direct_prompt` is deprecated upstream (migration table says use `prompt`). Renamed the input in the action call — content unchanged. ## Verification `actionlint` on all nine files: the previous `property "total" is not defined` / `input "direct_prompt" is not defined` findings are gone; remaining findings are pre-existing shellcheck style notes in untouched script blocks. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Vuuw6bCHCoYyhT7Q6jXhRj Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
laurigates
added a commit
that referenced
this pull request
Jul 2, 2026
…timeouts (#19) > **Stacked on #18** (which is stacked on #17) — merge order: #17 → #18 → this. Retarget this PR to `main` before merging #18, or it will auto-close. ## What Adopts [claude-code-action](https://github.com/anthropics/claude-code-action) options we weren't using, all overridable per caller: | Input | Where | Default | Why | |---|---|---|---| | `use-sticky-comment` | 8 analysis workflows | `true` | One maintained PR comment per analysis instead of a new comment on every push — 8 analyses × N pushes was a lot of noise | | `allowed-bots` | 8 analysis workflows | `''` (`renovate[bot]` on security-deps) | The action allows **no** bots by default, so bot-authored PRs fail with "non-human actor". Deps audit triggers on lockfile changes — mostly Renovate PRs, so it allowlists renovate by default | | `max-budget-usd` | 8 analysis workflows | `0` (unlimited) | Per-run spend backstop via `--max-budget-usd`, relevant now that defaults are opus + 50 turns | | `timeout-minutes` / `timeout_minutes` | all Claude jobs | 30 (45 for `@claude`) | A wedged run currently holds a runner for GitHub's 6-hour default | | `allowed_bots` | claude-review | `claude[bot],claude` | Was hardcoded; now an input | ## Verification `actionlint` clean on all eleven files (only pre-existing shellcheck style notes remain). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Vuuw6bCHCoYyhT7Q6jXhRj Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
laurigates
added a commit
that referenced
this pull request
Jul 2, 2026
`just lint` only validated YAML syntax; the workflow edits in #17–#19 needed actionlint run by hand each time. This adds actionlint to the recipe via mise's aqua backend, with shellcheck integration disabled (`-shellcheck=`) because those style findings on `run:` blocks are accepted pre-existing noise — actionlint still checks expressions, action inputs, and workflow structure (it's what caught the broken outputs fixed in #18). Verified: `just lint` → "All workflow files are valid YAML." + "actionlint: clean". 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Vuuw6bCHCoYyhT7Q6jXhRj Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
laurigates
added a commit
that referenced
this pull request
Jul 3, 2026
… fix (#30) ## Summary Surgical reconciliation of `reusable-security-deps.yml` against the FVH upstream — ports exactly two deltas while preserving every local improvement from PRs #17/#18/#19 (model + max-turns inputs, allowed-bots input, sticky comments, max-budget-usd, timeout-minutes, structured_output JSON schema). - **Native bun audit**: the `bun)` audit case fell back to `npm audit`, which ENOLOCKs on bun repos (no `package-lock.json`), silently producing no audit results. `bun audit` reads `bun.lock` natively since Bun >=1.2.15 with no install needed. - **allowed-bots re-run posture**: dependency PRs are bot-authored (Renovate, release-please), and a GitHub re-run replays the original `pull_request` event whose sender is the bot — so the action's human-actor guard blocked re-runs under the old `renovate[bot]` default. The default is now `'*'`; the job is audit-and-comment only with a fixed prompt, so widening is safe. ## Changes - `.github/workflows/reusable-security-deps.yml` - `bun)` case: `npm audit --json` fallback → `bun audit --json`, with FVH's rationale comment. - `allowed-bots` input: default `'renovate[bot]'` → `'*'`; description updated to explain the `'*'` default and why. - FVH's re-run rationale ported as a comment next to the action's `allowed_bots:` line. - The `allowed-bots` **input is kept** (FVH hardcodes a literal `"*"`); callers can still narrow it. ## Verification - `just lint`: "All workflow files are valid YAML." and "actionlint: clean". - Diff manually verified to be confined to the two named spots; no local improvements regressed. ## Notes - FVH's cheaper-model choice (`haiku`, `max-turns 5`) and its machine-readable-counts prompt/output parsing were **deliberately not ported** — local PR #17 split models by job difficulty and local PRs #18/#19 moved output parsing to structured_output JSON schemas. - Branch `feat/analysis-diff-size-gate` (issue #25) touches this same file on a separate branch; whichever merges second may need a trivial rebase. Closes #23 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_017RvFaUeBffGUoT3ioujtXw Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
laurigates
added a commit
to laurigates/claude-plugins
that referenced
this pull request
Jul 3, 2026
…code-github-workflows (#1910) ## What Adds a **claude-code-action v1 Gotchas** section to `claude-code-github-workflows` covering four facts that each produced a silently-broken workflow in production (laurigates/.github#17–#19): 1. **Outputs are fixed** — the action exposes only `execution_file`/`branch_name`/`github_token`/`structured_output`/`session_id`; count-style outputs must flow through `claude_args --json-schema` and be read with `fromJSON(steps.<id>.outputs.structured_output || '{}').<field>` (the guard is required because job outputs evaluate on skipped steps). Includes a worked snippet. 2. **`allowed_bots` defaults to empty** — Renovate/release-please PRs fail with "non-human actor", and re-runs replay the original bot sender. 3. **Deprecated inputs** (`direct_prompt`, `max_turns`, `model`, …) may be silently ignored — a `direct_prompt` workflow can run with no prompt at all. 4. **Budget levers** — `--max-turns` / `--max-budget-usd` only (no token budget); both fail mid-run, and turn exhaustion shows as `error_max_turns` with a rotating failing-job set across re-runs. ## Why here Session evidence: auditing laurigates/.github's reusable workflows against the action docs found all eight analysis workflows with permanently-empty outputs and dead `fail-on-critical` gates (fixed in laurigates/.github#18). The gotchas are action-level, not repo-level, so they belong in the marketplace skill every repo loads. README not updated: the skill's catalog entry/description is unchanged — this is an additive section within the existing skill. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Vuuw6bCHCoYyhT7Q6jXhRj 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.
What
Bumps the default
max-turnson every Claude-powered workflow to 50 (was 5–6 on the analysis workflows, 20–30 elsewhere) and replaces the flat--model haikuwith a difficulty-based opus/sonnet split.Every analysis workflow gains a
modelinput so callers can override the model the same way they already can overridemax-turns(and the review/auto-fix workflows keep theirclaude_argsoverride).Model split
reusable-security-owasp,reusable-quality-async,reusable-a11y-wcag,reusable-claude-review,reusable-claude(@claude mentions),reusable-auto-fixreusable-security-secrets,reusable-security-deps,reusable-quality-typescript,reusable-quality-code-smell,reusable-a11y-aria,reusable-auto-resolve-conflictsWhy
The 5–6 turn haiku budgets flake on large PRs — jobs die with
error_max_turnsin a rotating subset across re-runs, producing red ❌s that are budget exhaustion rather than findings (see ForumViriumHelsinki/.github#79 for the same failure class). 50 turns gives the analyses room to actually finish, and stronger models reduce wasted turns per finding.Notes
@main, so this takes effect on the next freshpull_requestevent after merge (re-runs replay the old resolution).🤖 Generated with Claude Code
https://claude.ai/code/session_01Vuuw6bCHCoYyhT7Q6jXhRj